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

C++ decltype,具有两个参数,=decltype(a,b),用于函数返回类型,c++,sfinae,C++,Sfinae,我遇到了一个decltype(),其中有两个参数作为模板函数的返回值类型: template<class C, class F> auto test(C c, F f) -> decltype((void)(c.*f)(), void()) { } 模板 自动测试(C C,F)->decltype((void)(C.*F)(),void()){} 有人知道第二个参数是什么吗,void()? 非常感谢。在表达式(void)(c.*f)()中,void(): (void)(c

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

template<class C, class F>
auto test(C c, F f) -> decltype((void)(c.*f)(), void()) { }
模板
自动测试(C C,F)->decltype((void)(C.*F)(),void()){}
有人知道第二个参数是什么吗,
void()
? 非常感谢。

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

  • (void)(c.*f)(
    用于检查
    f
    是否是
    c
    中的成员函数,可以无参数调用;不管成员函数返回类型是什么,但它名义上被转换为
    void

  • 如果上述内容有效,逗号运算符将丢弃该内容并考虑第二部分,这样总体效果将根据
    decltype(void())
    ,从而生成
    void
    类型

裁判官在下面评论说,尾随的
,void()
是多余的,因为前面的部分被转换为
void
(C型转换
(void)
)。。。我怀疑
,void()
是作为文档使用的,突出显示了
enable\u如果
类似于返回类型的条件选择,那么是否将其进一步缩短为
decltype((c.*f(),void())
,则是一种样式选择

进一步详情/例子 这可以用于,但更多的是自我记录。考虑这个代码,以及在<代码>主体()/<代码>(CT代表编译时间)中的注释:


您可以查看并运行代码。

谢谢您的回答,Tony D。decltype检查c似乎有一个成员函数void f()。请允许我确认“如果上述内容有效”部分。是否“如果上述内容无效”?我很困惑,因为这两个参数都返回void。如果我误解了什么。很抱歉确认上述内容。非常感谢。“两个参数都返回void”呃?函数的返回类型被强制转换为
void
无论如何,(void)(c.*f)()和void()的返回类型都是void,因此
,void()部分是多余的。如果(void)(c.*f)()有效,为什么它不应用decltype((void)(c.*f)())?这使我困惑。我是C++初学者。所以我恐怕我问了一些奇怪的问题。如果是这样,请原谅我。非常感谢。我了解到第一个增广是SFINAE的有效检查器。现在我明白了为什么decltype()需要有两个参数:有效检查器(=第一个扩充)和返回类型(=第二个扩充)。非常感谢大家。
#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