Decltype with two parameters, = decltype (a, b), for the return type of the function
In the expression (void)(c.*f)(), void()
:
-
(void)(c.*f)()
serves to check whatf
is a member function inc
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 .
source to share