how to implement "contains a member" template ?

Discussion in 'C++' started by Gianni Mariani, May 14, 2004.

  1. I remember seeing a neat template specialization trick posted here a few
    months ago that allowed the detection of a type containing a member.
    After a day searching through google archives I come up zip.


    Anyhow, after much trial and error I came up with this. This
    "contains_member" template sets value to 1 if the type D contains
    a typedef named MEMBER of type TD.


    ============== example.cpp ==================

    template <typename D, typename TD = int >
    struct contains_member
    {

    struct false_t { char m[2]; };
    typedef char true_t;

    struct XX : D
    {
    };

    struct finder_s
    {

    template <typename T>
    static true_t finder( const T *, typename T::MEMBER );

    static false_t finder( const D *, int );

    };

    typedef XX * XXp;

    enum {
    value =
    sizeof( finder_s::finder( XXp(), TD() ) ) == sizeof( true_t )
    };


    };


    struct A
    {
    virtual void f() = 0;
    };

    struct B
    : A
    {
    virtual void f() = 0;

    typedef int MEMBER;
    };

    struct C
    {
    typedef short MEMBER;
    };



    #include <iostream>


    int main()
    {
    std::cout << contains_member< B >::value << "\n";
    std::cout << contains_member< A >::value << "\n";
    std::cout << contains_member< C, short >::value << "\n";
    }

    ============== end example ==============



    Now I try to set make it more generic by allowing any member name.
    To do this I pass in a template template parameter that has a typedef
    that uses the member name. This does not work because during the
    attempt to instantiate the template "member" there is an error.

    So, this seems inconsistent. In the previous example, the compiler
    does not even bother because the template function finder can't be
    resolved while in the second case it also can't be resolved but it dumps
    an error.

    This is consistent with gcc 3.4.0, msc++ 7.1 and Comeau C/C++ 4.3.3.


    ============== example2.cpp =============

    template <typename D>
    struct member
    {
    typedef typename D::MEMBER type;
    };



    template <typename D, typename TD = int, template <typename> class MEM =
    member >
    struct contains_member
    {

    struct false_t { char m[2]; };
    typedef char true_t;

    struct XX : D
    {
    };

    struct finder_s
    {

    template <typename T>
    static true_t finder( const T *, typename MEM<T>::type );

    static false_t finder( const D *, int );

    };

    typedef XX * XXp;

    enum {
    value =
    sizeof( finder_s::finder( XXp(), TD() ) ) == sizeof( true_t )
    };


    };


    struct A
    {
    virtual void f() = 0;
    };

    struct B
    : A
    {
    virtual void f() = 0;

    typedef int MEMBER;
    };

    struct C
    {
    typedef int OTHERMEMBER;
    };


    template <typename D>
    struct othermember
    {
    typedef typename D::OTHERMEMBER type;
    };



    #include <iostream>


    int main()
    {

    std::cout << contains_member< B >::value << "\n";
    std::cout << contains_member< A >::value << "\n";
    std::cout << contains_member< C, int, othermember >::value << "\n";

    }

    ====================================

    Any easier way to do this ?
     
    Gianni Mariani, May 14, 2004
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Theis
    Replies:
    2
    Views:
    500
    Chris Theis
    Jul 24, 2003
  2. tom_usenet
    Replies:
    0
    Views:
    566
    tom_usenet
    Jul 24, 2003
  3. Replies:
    1
    Views:
    2,147
    Gianni Mariani
    Jun 8, 2007
  4. Peng Yu
    Replies:
    3
    Views:
    805
    Thomas J. Gritzan
    Oct 26, 2008
  5. nguillot
    Replies:
    5
    Views:
    559
Loading...

Share This Page