Template specialization

  • Thread starter Vladimir Nesterovsky
  • Start date
V

Vladimir Nesterovsky

Hello,

I have a code which behaves differently if template parameter has a
specified member:

#include <iostream>

template<class T, bool (T::*)()>
class member_bind
{
public:
typedef T type;
};

template<class T1, class T2>
class has_member
{
public:
static const bool value = false;
};

// 1
template<class T>
class has_member<T, typename member_bind<T, T::member>::type>
{
public:
static const bool value = true;
};

class A
{
public:
bool member();
};


class B {};

int main(int argc, char* argv[])
{
std::cout << "A has member? " << (has_member<A, A>::value ? "yes" :
"no") << std::endl;
std::cout << "B has member? " << (has_member<B, B>::value ? "yes" :
"no") << std::endl;

return 0;
}

I've been able to compile only this code variation. In my opinion, however,
the following lines ain't strictly correct:

// 1
template<class T>
class has_member<T, typename member_bind<T, T::member>::type>

They should be written as:

template<class T>
class has_member<T, typename member_bind<T, &T::member>::type>

or maybe even without "typename" keyword (member_bind is known template and
have no uncertainties) as:

template<class T>
class has_member<T, member_bind<T, &T::member>::type>

Is it a bug in compiler?
 
T

tom_usenet

On Tue, 13 Jul 2004 11:56:45 +0200, "Vladimir Nesterovsky"

To simplify usage of the template, you might want:
I've been able to compile only this code variation. In my opinion, however,
the following lines ain't strictly correct:

// 1
template<class T>
class has_member<T, typename member_bind<T, T::member>::type>

They should be written as:

template<class T>
class has_member<T, typename member_bind<T, &T::member>::type>

Yes, that is the correct version - member function addresses always
require the &.
or maybe even without "typename" keyword (member_bind is known template and
have no uncertainties) as:

template<class T>
class has_member<T, member_bind<T, &T::member>::type>

Nope, typename is required, since it isn't known whether "type" is a
type or not (remember that member_bind might be specialized). With
members of dependent templates, typename is always required for types.
Is it a bug in compiler?

Looks like it. You might consider using the SFINAE version instead,
with overloading and sizeof:


#include <iostream>

template<class T, bool (T::*)()>
class member_bind
{
public:
typedef T type;
};

template<class T1>
class has_member
{
private:
typedef char (&twochars)[2];

template <class U>
static char test(member_bind<U, &U::member>*);

template <class U>
static twochars test(...);
public:
static const bool value = sizeof(test<T1>(0)) == 1;
};

class A
{
public:
bool member();
};


class B {};

int main(int argc, char* argv[])
{
std::cout << "A has member? " << (has_member<A>::value ? "yes" :
"no") << std::endl;
std::cout << "B has member? " << (has_member<B>::value ? "yes" :
"no") << std::endl;

std::cin.ignore();
return 0;
}

That seems to work on gcc and vc, and looks legal to me.

Tom
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top