I’ve been working on some solutions for some questions that have been recently posted where the original questioners have been trying to query if a method exists in a given class. I’ve been trying to develop a solution using a SFINAE approach, but unfortunately I keep coming up empty.
Here was my attempt at a solution that isn’t working for a class that allows us to detect if another class has a method called function():
#include <iostream>
using namespace std;
struct sample_class
{
void function() {}
};
template<typename T>
class test_size_call
{
private:
typedef char yes;
typedef char (&no)[2];
int tester[1];
template <unsigned int>
struct helper { static const unsigned int value = 1; };
template<typename R>
static yes test(int (&a)[helper<sizeof(std::declval<R>().function(), 0)>::value]);
/* template<typename R>
static no test(...); */
public:
static const bool value = (sizeof(test<T>(tester)) == sizeof(yes));
};
int main()
{
cout << "Has function() method: " << test_size_call<sample_class>::value << endl;
return 0;
}
The results, if you uncomment the catch-all test function, keep coming up as false. With the function commented out, I get a compiler error that there is not version of test that will take a int (&)[1] argument. I’m curious why the declval<R>().function() doesn’t seem to be instantiating properly. For instance, if I changed it to something very explicit, like declval<T>().function() then it works. Unfortunately that’s not SFINAE, because if the class doesn’t have a function() method, rather than failing silently, I get a compiler error.
I’m sure there is something really simple I’m missing here. Thanks for any help you can provide.
Must be a problem with your compiler, Clang correctly prints
1and0for the following code:While GCC 4.5.1 does not. Note that it’s fixed in GCC 4.7, as pointed out here.