我希望能够通过布尔指定我需要在编译时使用哪两个变量,所有这些没有直接的SFINAE 。只有一个函数,类似于std::conditional
但不返回类型。
因此,例如在课程test
中,我想要
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;
}
使用很简单:如果我指定first == true
,那么它应该使用var == var1
应用循环,否则var == var2
。
有可能吗?
答案 0 :(得分:5)
只是为了好玩(*),对当前代码段的 minimal C ++ 17(**)修改可能
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);
}
};
(*)我认为没有哪种情况比其他建议的解决方案更可取......
(**)据我所知,由于模板非类型指针参数的链接要求,这需要C ++ 17 ...
答案 1 :(得分:4)
对于C ++ 17及以上版本:
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;
}
如果条件是constexpr,则在编译时评估 if constexpr
,这是模板参数的情况。
答案 2 :(得分:2)
你可以在C ++ 11中使用指向数据成员的指针:
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;
}
答案 3 :(得分:1)
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
在编译时选择列表中的内容。
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;
};
我在复制粘贴时也做了一些小改进。