当我有一个带有成员函数的结构,我专注于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";
}
};
提前致谢!
就像任何模板化方法一样:
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";
}
请注意,此处没有模板特化(您不能对成员函数进行部分特化),您有不同的重载。
我会编写不同的辅助函数和标记调度。
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
也取决于你; if constexpr
in C ++ 17,在C ++ 11/14中使用或者static_if
或SFINAE或traits类构造。
我会认为get_tag
的定义是analyze
未实现的接口的一部分;而不是使用enable如果直接我们分离重载决策规则,公开它,然后将业务逻辑的实现放在别处。
我认为匿名默认模板参数是一个更好的解决方案,因为您不必复制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";
}
我知道它不适合具体的例子,因为它确实回答了这个问题。