I am trying to replicate the (I guess) typical SFINAE example to tell whether a type has a certain method. My code is basically the one found in the accepted answer of a previous popular question on the topic:
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <list>
template <typename T>
class has_push_back_sfinae {
typedef int8_t yes;
typedef int16_t no;
template <typename C> static constexpr yes test(decltype(&C::push_back));
template <typename C> static constexpr no test(...);
public:
static constexpr bool value = (sizeof(test<T>(0)) == sizeof(yes));
};
template <typename T>
constexpr bool has_push_back = has_push_back_sfinae<T>::value;
int main() {
std::cout << std::boolalpha;
std::cout << has_push_back<int> << std::endl;
std::cout << has_push_back<std::set<int>> << std::endl;
std::cout << has_push_back<std::map<int, char>> << std::endl;
std::cout << has_push_back<std::vector<char>> << std::endl;
std::cout << has_push_back<std::list<int>> << std::endl;
std::cout << has_push_back<std::string> << std::endl;
return 0;
}
Basically, has_push_back<T>
is meant to be true
if and only if push_back
is a method of T
. I expected that my output had 3 false
lines, followed by 3 true
ones. However, this is the actual output:
false
false
false
false
false
true
Am I missing something?
(PS: Is there any more standard or nicer way to write such a class?)