By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,413 Members | 1,017 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,413 IT Pros & Developers. It's quick & easy.

how to implement "contains a member" template ?

P: n/a

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 ?


Jul 22 '05 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.