Boost logo

Boost :

Subject: Re: [boost] Workaround for compiler bugs
From: Stephan T. Lavavej (stl_at_[hidden])
Date: 2010-12-06 19:43:45


[Edward Diener]
> You missed the fact in the attachment that the T passed in must be the
> full signature of a pointer to data member, as in 'Gipf Dvonn::*' in
> your first example below.

I wasn't sure if mentioning the data member's type was a desired feature of your code. Here's how to achieve that:

C:\Temp>type meow.cpp
#include <type_traits>

#define DEFINE_HAS_MEMBER_OF_TYPE(NAME) \
template <typename T> class has_member_ ## NAME { \
private: \
    template <typename U> static std::true_type helper(decltype(&U::NAME)); \
    template <typename U> static std::false_type helper(...); \
public: \
    typedef decltype(helper<T>(nullptr)) type; \
    static const bool value = type::value; \
}; \
                                                                            \
template <typename T, typename X, bool B> \
    struct has_member_ ## NAME ## _of_type_helper \
    : public std::false_type { }; \
                                                                            \
template <typename T, typename X> \
    struct has_member_ ## NAME ## _of_type_helper<T, X, true> \
    : public std::is_same<decltype(&T::NAME), X T::*> { }; \
                                                                            \
template <typename T, typename X> \
    struct has_member_ ## NAME ## _of_type \
    : public has_member_ ## NAME ## _of_type_helper< \
        T, X, has_member_ ## NAME<T>::value> { };

DEFINE_HAS_MEMBER_OF_TYPE(cMem)

struct Gipf { };

struct Dvonn {
    Gipf cMem;
};

struct Tzaar {
    int cMem;
};

struct Yinsh {
    int Zertz;
};

int main() {
    static_assert( has_member_cMem_of_type<Dvonn, Gipf>::value, "one");
    static_assert(!has_member_cMem_of_type<Dvonn, int>::value, "two");

    static_assert(!has_member_cMem_of_type<Tzaar, Gipf>::value, "three");
    static_assert( has_member_cMem_of_type<Tzaar, int>::value, "four");

    static_assert(!has_member_cMem_of_type<Yinsh, Gipf>::value, "five");
    static_assert(!has_member_cMem_of_type<Yinsh, int>::value, "six");
}

C:\Temp>cl /EHsc /nologo /W4 meow.cpp
meow.cpp

C:\Temp>

Note that these macros do not attempt to avoid the formation of Standard-forbidden double underscores when given data member names with leading or trailing underscores. (Conveniently, I hate such names.)

STL


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk