SFINAE fun (or failure...)
Goals:
- Enable static polymorphism. Call a function if and if it exists.
Problems:
- Implementation defined (or undefined behaviour).
Code:
Code:
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <cctype>
#include <fstream>
#include <vector>
#include <type_traits>
#include <typeinfo>
#include <utility>
#include <functional>
template<typename T>
struct Has_Subscribe
{
typedef char yes[1];
typedef char no[2];
template<typename C> static yes& test(decltype(C::Subscribe)*);
template<typename C> static no& test(...);
const static bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
};
template<typename Parent_t>
struct base
{
base()
{
test<Parent_t>();
}
template<typename T>
auto test() -> typename std::enable_if<Has_Subscribe<T>::value>::type { std::cout << "yes!\n"; }
template<typename T>
auto test() -> typename std::enable_if<!Has_Subscribe<T>::value>::type { std::cout << "no!\n"; }
};
struct foo: public base<foo>
{
void Subscribe(int) {}
};
struct foo2: public base<foo2> {};
int main()
{
foo _foo;
foo2 _foo2;
std::cout << "\n";
}
VS output:
yes!
no!
(Correct output. In this case.)
Clang output:
no!
no!
(Incorrect output in this case.)
This is a sample demonstrating the problem. In the real code, I tend to get even worse results, leading me to think that this is the source of the problem.
Either there is something I am not aware of, or this method of detecting if members exist do not work.
Or there are bugs in the compilers.
Anyone who can shed some light on the problem?