当我有一个带有成员函数的结构,我专注于std::enable_if
时,我怎么能从实现中拆分声明?
示例代码(在ideone中)
struct node
{
template < class T >
void analyze(T t, typename std::enable_if<std::is_integral<T>::value>::type* = 0)
{
std::cout << "is_arithmetic type " << t << "\n";
}
template < class T >
void analyze(T t, typename std::enable_if<std::is_floating_point<T>::value>::type* = 0)
{
std::cout << "is_floating_point type " << t << "\n";
}
void analyze(bool t)
{
std::cout << "is bool type " << t << "\n";
}
};
提前致谢!
答案 0 :(得分:4)
就像任何模板化方法一样:
struct node {
template <class T>
void analyze(T t, typename std::enable_if<std::is_integral<T>::value>::type* = 0);
};
template <class T>
void node::analyze(T t, typename std::enable_if<std::is_integral<T>::value>::type*) {
std::cout << "is_arithmetic type " << t << "\n";
}
请注意,这里没有模板特化(你不能对成员函数进行部分特化),你有不同的重载。
答案 1 :(得分:1)
我会编写不同的辅助函数和标记调度。
template < class T >
void analyze(T t, int_tag);
template < class T >
void analyze(T t, float_tag );
void analyze(bool t, bool_tag );
template<class T>
auto get_tag();
void analyze( T t ){ return analyze(t, get_tag<T>());
现在我们通过标签分派从过载中分离过载路由(get_tag
)。
如何定义代码(std::integral_constant
或struct int_tag
或tag<int>
或其他)取决于您;他们只是互相矛盾和空虚。
如何编写get_tag
也取决于您; C ++ 17中的if constexpr
,在C ++ 11/14中使用或static_if
或SFINAE或traits类构造。
我认为get_tag
的定义是analyze
未实现的接口的一部分;而不是使用enable如果直接我们将重载决策规则分开,公开它,然后将业务逻辑的实现放在别处。
答案 2 :(得分:0)
我认为匿名默认模板参数是一个更好的解决方案,因为您不必两次复制enable_if条件。
struct node
{
template <class T, typename = std::enable_if_t<std::is_integral_v<T>>>
void analyze( T t );
};
template <class T, typename>
void node::analyze( T t )
{
std::cout << "is_arithmetic type " << t << "\n";
}
我知道它不适合特定示例,因为它确实回答了问题。