我遇到了decltype()
,其中有两个参数作为模板函数的返回值类型:
template<class C, class F>
auto test(C c, F f) -> decltype((void)(c.*f)(), void()) { }
有人知道第二个参数void()
是什么?
非常感谢你。
答案 0 :(得分:9)
在表达式(void)(c.*f)(), void()
中:
(void)(c.*f)()
用于检查f
是c
中可以不带参数调用的成员函数;无论如何,成员函数返回类型并不重要,但它名义上被转换为void
如果以上内容有效,逗号操作员会丢弃它并考虑第二部分,以便整体效果为decltype(void())
,从而产生void
类型
下面的Praetorian评论说尾随, void()
是多余的,因为无论如何,主要部分被转换为void
(C风格的演员(void)
)......我怀疑{{{} 1}}用作文档,突出显示, void()
- 类似于返回类型的条件选择,它是一种风格选择,是否进一步缩短到enable_if
。
这可用于SFINAE,但enable_if
更具自我记录功能。考虑一下这段代码,以及decltype((c.*f)(), void())
中的注释(CT代表编译时间):
main()
输出:
#include <iostream>
template<class C, class F>
auto test(C c, F f) -> decltype((void)(c.*f)(), void())
{ std::cout << "member function\n"; }
template<class C>
void test(C c, int)
{ std::cout << "int\n"; }
struct X {
int f() { return 42; }
double g(int) { return 3.14; }
};
int main()
{
X x;
test(x, &X::f); // ok - outputs "member function\n"
// test(x, &X::g); // CT error - g needs an argument
test(x, 99); // ok - outputs "int\n"
}
您可以查看并运行代码here。