dimanche 14 octobre 2018

Dectecting template methods with SFINAE

I have a simple trait struct hasMemberSerialize that I am trying to use to determine if any given class is compatible with callSerialize(). The struct looks like so:

template<typename Type, typename ArchiveType>
struct hasMemberSerialize {
    template<typename T, typename A>
    static auto test(int) -> decltype(Serialization::access::callSerialize(std::declval<A&>(), std::declval<T&>()), std::true_type);

    template<typename, typename>
    static std::false_type test(...);

    static const bool value = std::is_same<decltype(test<Type, ArchiveType>(0)), std::true_type>::value;
};

This compiles and runs fine, however, my hasMemberSerialize::value is always std::false_type. I've used a similar approach to check for non-template methods; however, the callSerialize() method I am checking looks something like:

template<typename Archive, typename Type>
static auto callSerialize(Archive& a, Type& t) -> decltype(t.serialize(a)) {
    // Implementation
}

I did some tests using std::cout like so:

Serialization::access::callSerialize(JSON, myType);

std::cout << std::boolalpha
    << hasMemberSerialize<MyType, JSONOutputArchive>::value << std::endl;

The method call callSerialize(JSON, myType) works as expected and serializes the type; however, hasMemberSerialize::value prints false. finally, myType is a simple test class:

class MyType {
    int myInt;

public:
    MyType() : myInt(4) {}

    template<typename Archive>
    void serialize(Archive& a) {
        a(myInt);
    }
};

...

MyType myType;

Aucun commentaire:

Enregistrer un commentaire