【发布时间】:2015-06-24 03:20:39
【问题描述】:
我遇到了一个decltype(),有两个参数作为模板函数的返回值类型:
template<class C, class F>
auto test(C c, F f) -> decltype((void)(c.*f)(), void()) { }
有人知道第二个参数void() 是什么吗?
非常感谢。
【问题讨论】:
我遇到了一个decltype(),有两个参数作为模板函数的返回值类型:
template<class C, class F>
auto test(C c, F f) -> decltype((void)(c.*f)(), void()) { }
有人知道第二个参数void() 是什么吗?
非常感谢。
【问题讨论】:
在表达式(void)(c.*f)(), void():
(void)(c.*f)() 用于检查f 是c 中的成员函数,可以不带参数调用;无论如何,成员函数的返回类型是什么并不重要,但名义上它被强制转换为void
如果上述内容有效,则逗号运算符将其丢弃并考虑第二部分,因此整体效果符合decltype(void()),产生void 类型
Praetorian cmets 下面的尾随 , void() 是多余的,因为无论如何,前导部分都转换为 void(C 风格转换 (void))......我怀疑 , void() 是为了作为文档,突出显示返回类型的enable_if-like 条件选择,是否将其进一步缩短为decltype((c.*f)(), void()) 是一种样式选择。
这可用于SFINAE,尽管enable_if 更具自我记录性。考虑这段代码,以及main()(CT 代表编译时间)中的 cmets:
#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"
}
输出:
member function
int
你可以看到并运行代码here。
【讨论】:
, void() 部分是多余的,因为函数的返回类型无论如何都会转换为 void