Decltype with two parameters, = decltype (a, b), for the return type of the function

I came across decltype()

two parameters as the return type of a template function:

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

      

Does anyone know what the second parameter is void()

,? Thank you very much.

+3


source to share


1 answer


In the expression (void)(c.*f)(), void()

:

  • (void)(c.*f)()

    serves to check what f

    is a member function in c

    that can be called without arguments; it doesn't matter what the return type of the member function is anyway, but it is nominally cast tovoid

  • if that's true, the comma operator discards it and considers the second part, so the overall effect is decltype(void())

    , which gives the typevoid

Praetorian comments below that the trailing , void()

is redundant since the leading part is being discarded on void

(C-style listing (void)

) ... I suspect it is , void()

intended as documentation, highlighting the enable_if

-like conditional return type choice is a style choice to shorten that to decltype((c.*f)(), void())

.

Additional information / example

This can be used for SFINAE , although enable_if

more self-documenting. Consider this code, and the comments in main()

(CT stands for Compile Time):



#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"
}

      

Output:

member function
int

      

You can see and run the code here .

+9


source







All Articles