具有两个参数的decltype,= decltype(a,b),用于函数返回类型

时间:2015-06-24 03:20:40

标签: c++ sfinae

我遇到了decltype(),其中有两个参数作为模板函数的返回值类型:

template<class C, class F>
auto test(C c, F f) -> decltype((void)(c.*f)(), void()) { }

有人知道第二个参数void()是什么? 非常感谢你。

1 个答案:

答案 0 :(得分:9)

在表达式(void)(c.*f)(), void()中:

  • (void)(c.*f)()用于检查fc中可以不带参数调用的成员函数;无论如何,成员函数返回类型并不重要,但它名义上被转换为void

  • 如果以上内容有效,逗号操作员会丢弃它并考虑第二部分,以便整体效果为decltype(void()),从而产生void类型

    < / LI>

下面的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