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

mor*_*ora 3 c++ sfinae

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

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

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

Ton*_*roy 9

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

  • (void)(c.*f)()用于检查是否f是一个成员函数c,可以不带参数调用; 无论成员函数返回类型是什么都没关系,但它名义上被转换为void

  • 如果以上内容有效,则逗号运算符将其丢弃并考虑第二部分,以使整体效果为per decltype(void()),从而产生一种void类型

Praetorian在下面评论说尾随, void()是多余的,因为主要部分被投射到void(C风格的演员阵容(void))无论如何...我怀疑它, void()是作为文档,突出了enable_if类似返回类型的条件选择,它是一种风格选择是否进一步缩短decltype((c.*f)(), void()).

进一步细节/例子

这可以用于SFINAE,但enable_if更自我记录.考虑这段代码,以及main()(CT代表编译时间)中的注释:

#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"
}
Run Code Online (Sandbox Code Playgroud)

输出:

member function
int
Run Code Online (Sandbox Code Playgroud)

您可以在此处查看和运行代码.

  • `,void()`部分是多余的,因为函数的返回类型无论如何都被转换为`void` (2认同)