因此对于 SFINAE 和 c++11,可以根据其中一个模板参数是否可以被替换来实现两个不同的模板函数。
例如
struct Boo{
void saySomething(){ cout << "Boo!" << endl; }
};
template<class X>
void makeitdosomething(decltype(&X::saySomething), X x){
x.saySomething();
}
template<class X>
void makeitsaysomething(int whatever, X x){
cout << "It can't say anything!" << endl;
}
int main(){
makeitsaysomething(3);
makeitsaysomething(Boo());
}
或者类似的东西。
我的问题是..如何做同样的事情,但对于非成员函数?
特别是我正在尝试检查是否有这样的东西:
operator<<(std::ostream& os, X& whateverclass);
存在。可以测试吗?
编辑:问题不同于:Is it possible to write a template to check for a function's existence?因为我试图查看函数是否存在,而不是方法
最佳答案
我找到了 void_t
通常比其他答案中显示的传统 SFINAE 方法更可取的技巧。
template<class...> using void_t = void; // now in the C++17 working paper!
// GCC <= 4.9 workaround:
// template<class...> struct voider { using type = void; };
// template<class... T> using void_t = typename voider<T...>::type;
template<class, class = void>
struct is_ostreamable : std::false_type {};
template<class T>
struct is_ostreamable<T, void_t<decltype(std::declval<std::ostream&>() <<
std::declval<T>())>> : std::true_type {};
当且仅当表达式的格式正确时,才会选择偏特化。
Demo .
请注意 &
在std::declval<std::ostream&>()
很重要,因为否则 std::declval<std::ostream>()
是一个右值,你会得到 ostream
的 catchall 右值流插入运算符,并报告一切都是可流式的。
以上代码检查 operator<<
可以接受 T
右值。如果你想检查一个接受左值的 T
, 然后使用 std::declval<T&>()
.
关于c++ - 通过模板检查 c++11 中是否存在函数(不是方法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29319000/