Select a variable at compile time

I would like to be able to specify through a boolean which of the two variables that I need to use at compile time, all of this without direct SFINAE . Only one function, similar to std::conditional , but not returning types.

So, for example, in the test class, I would like to have

 class test { template <class T, bool first, MAGIC_HAPPENS var> void apply_it(T &t) { for (auto &p : var) p.apply(t); } std::vector<myfunction> var1; std::vector<myfunction> var2; } 

The use is simple: if I specify first == true , then it should apply a loop with var == var1 , otherwise var == var2 .

Is it possible?

+5
source share
4 answers

Just for fun (*) the minimal C ++ 17 (**) modification for your current code snippet could be

 class test { std::vector<myfunction> var1; std::vector<myfunction> var2; template <class T, bool first, std::vector<myfunction> test::*var = first ? &test::var1 : &test::var2 > void apply_it(T &t) { for (auto &p : this->*var) p.apply(t); } }; 

(*) I do not see a situation in which such a thing would be preferable to other proposed solutions ...

(**), as far as I know, this requires C ++ 17 because of the need to bind the parameters of the template pointer not of type ...

+5
source

For C ++ 17 and above:

 class test { template <class T, bool first> void apply_it(T &t) { if constexpr (first) { for (auto &p : var1) p.apply(t); } else { for (auto &p : var2) p.apply(t); } } std::vector<myfunction> var1; std::vector<myfunction> var2; } 

if constexpr is evaluated at compile time, if the condition is constexpr, which is the case for template parameters.

+4
source

You can do this in C ++ 11 with a pointer to a data element:

 class test { template <class T, bool first> void apply_it(T &t) { constexpr auto var = first ? &test::var1 : &test::var2; for (auto &p : this->*var) p.apply(t); } std::vector<myfunction> var1; std::vector<myfunction> var2; } 
+2
source
 template<std::size_t I, class...Args> decltype(auto) pick( Args&&... args ) { return std::get<I>( std::forward_as_tuple( std::forward<Args>(args)... ) ); } 

pick at compile time selects something from the list.

 class test { template <bool first, class T> void apply_it(T&& t) { auto&& var = pick<first?0:1>(var1, var2); for (auto&& p : var) p.apply(t); } std::vector<myfunction> var1; std::vector<myfunction> var2; }; 

I also made some minor improvements while I was copying the insert.

+1
source

Source: https://habr.com/ru/post/1274101/


All Articles