I\'m asking for a template trick to detect if a class has a specific member function of a given signature.
The problem is similar to the one cited here http://www.go
To accomplish this we'll need to use:
true_type
overload expecting an int
and the false_type
overload expecting Variadic Parameters to exploit: "The lowest priority of the ellipsis conversion in overload resolution"true_type
function we will use declval and decltype allowing us to detect the function independent of return type differences or overloads between methodsYou can see a live example of this here. But I'll also explain it below:
I want to check for the existence of a function named test
which takes a type convertible from int
, then I'd need to declare these two functions:
template ().test(declval))> static true_type hasTest(int);
template static false_type hasTest(...);
decltype(hasTest(0))::value
is true
(Note there is no need to create special functionality to deal with the void a::test()
overload, the void a::test(int)
is accepted)decltype(hasTest(0))::value
is true
(Because int
is convertable to double
int b::test(double)
is accepted, independent of return type)decltype(hasTest(0))::value
is false
(c
does not have a method named test
that accepts a type convertible from int
therefor this is not accepted)This solution has 2 drawbacks:
test()
method?So it's important that these functions be declared in a details namespace, or ideally if they are only to be used with a class, they should be declared privately by that class. To that end I've written a macro to help you abstract this information:
#define FOO(FUNCTION, DEFINE) template ().FUNCTION)> static true_type __ ## DEFINE(int); \
template static false_type __ ## DEFINE(...); \
template using DEFINE = decltype(__ ## DEFINE(0));
You could use this like:
namespace details {
FOO(test(declval()), test_int)
FOO(test(), test_void)
}
Subsequently calling details::test_int::value
or details::test_void::value
would yield true
or false
for the purposes of inline code or meta-programming.