I'd like to be able to specify via a boolean which of two variables I need to use at compile time, all of this without direct SFINAE . Just one single function, similar to std::conditional
but not returning types.
So for instance in a class test
, I'd 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 the loop with var == var1
, otherwise var == var2
.
Is it possible?
Just for fun(*), a minimal C++17(**) modification to your current code snippet might 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 see no situation in which such a thing would be preferable over the other suggested solutions ...
(**) as far as I know, this requires C++17 due to linkage requirement of template non type pointer parameters ...
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.
You can do that in C++11 with a pointer to data member:
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;
}
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
selects at compile time something from a 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 copy pasting.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.