我指的是这个例子SFINAE example,
我试图运行该示例,
//enable_if
template<bool, typename T = void>
struct enable_if {};
template <typename T>
struct enable_if<true, T> {
using type = T;
};
template <typename T>
void do_stuff(typename enable_if<std::is_integral<T>::value, T>::type &t) {
std::cout<< "Integral selected "<<std::endl;
}
template <typename T>
void do_stuff(typename enable_if<std::is_class<T>::value, T>::type &t) {
std::cout<<"Class selected " <<std::endl;
}
int main()
{
int t =25;
do_stuff(t);
return 0;
}
但是这不会编译,我可以知道为什么吗?
答案 0 :(得分:3)
除了其他解决方案之外,如果您不希望将enable_if
作为返回值,则可以将其作为参数类型传递,然后将其作为函数签名的一部分:
#include <type_traits>
#include <iostream>
//enable_if
template<bool, typename T = void>
struct enable_if {};
template <typename T>
struct enable_if<true, T> {
using type = int; // must be a non-type template parameter
};
template <typename T, typename enable_if<std::is_integral<T>::value, T>::type = 0>
void do_stuff(T &t) {
std::cout<< "Integral selected "<<std::endl;
}
template <typename T, typename enable_if<std::is_class<T>::value, T>::type = 0>
void do_stuff(T &t) {
std::cout<<"Class selected " <<std::endl;
}
class Foo
{
public:
Foo() = default;
};
int main()
{
int t =25;
Foo f;
do_stuff(t);
do_stuff(f);
return 0;
}
答案 1 :(得分:1)
这对我有用:
template <typename T>
typename enable_if<std::is_integral<T>::value, void>::type
do_stuff(T& t) {
std::cout<< "Integral selected "<<std::endl;
}
template <typename T>
typename enable_if<std::is_class<T>::value, void>::type
do_stuff(T& t) {
std::cout<<"Class selected " <<std::endl;
}
问题是enable_if
静态调用应用于函数参数而不是返回类型。
答案 2 :(得分:0)
但是这不会编译,我可以知道为什么吗?
因为,调用do_stuff()
类型T
无法通过enable_if
推断出来。
但如果您致电do_stuff()
来说明T
int t =25;
do_stuff<int>(t); // compile
为了避免这个问题,我建议您使用Nicolas Tisserand(+1)提出的解决方案(不需要将void
作为enable_if
的第二个参数进行说明,因为它是默认值)
template <typename T>
typename enable_if<std::is_integral<T>::value>::type
do_stuff(T& t) {
std::cout<< "Integral selected "<<std::endl;
}
template <typename T>
typename enable_if<std::is_class<T>::value>::type
do_stuff(T& t) {
std::cout<<"Class selected " <<std::endl;
}
通过返回类型启用SFINAE。
这种类型T
可以从参数中推断出来,所以你不需要解释它。