通过模板检查c ++ 11中是否存在函数(不是方法) [英] Checking whether a function (not a method) exists in c++11 via templates
问题描述
因此,使用SFINAE和c ++ 11,可以根据是否可以替换其中一个模板参数来实现两个不同的模板函数。
So with SFINAE and c++11, it is possible to implement two different template functions based on whether one of the template parameters can be substituted.
例如
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());
}
或类似的东西。
我的问题是..一个人怎么做同样的事情,但是对于非成员函数呢?
My question is.. how does one do the same thing, but for non-member functions?
特别是我正在尝试检查是否存在例如:
In particular I'm trying to check if there's such thing as an:
operator<<(std::ostream& os, X& whateverclass);
存在。可以测试吗?
编辑:问题不同于:是吗?可以编写一个模板来检查函数是否存在?,因为我试图查看函数是否存在,而不是方法
edit: the question is different to : Is it possible to write a template to check for a function's existence? in that I'm trying to see whether a function exists, not a method
推荐答案
我发现 void_t
技巧通常比其他答案中所示的传统SFINAE方法更可取。
I find the void_t
trick to be usually preferable to the traditional SFINAE method shown in the other answer.
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 {};
仅当表达式格式正确时,才选择部分专业化。
The partial specialization is selected if and only if the expression is well-formed.
演示。
请注意, std :: declval< std :: ostream&()
中的&
之所以重要,是因为否则 std :: declval< std :: ostream>()
是一个右值,您会得到 ostream $ c $
Demo.
Note that the &
in std::declval<std::ostream&>()
is important, because otherwise std::declval<std::ostream>()
is an rvalue and you'll get ostream
's catchall rvalue stream insertion operator, and report that everything is streamable.
上面的代码检查 operator<< code>可以接受
T
右值。如果要检查一个接受左值 T
的值,则使用 std :: declval< T&>()
。
The above code checks for an operator<<
that can accept a T
rvalue . If you want to check for one that accepts an lvalue T
, then use std::declval<T&>()
.
这篇关于通过模板检查c ++ 11中是否存在函数(不是方法)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!