using templates to check for member variable not working on int
I need to check and see if a given type has a member variable. However when a type that is not a class or a struct is given, I get a compiler error.
struct Vector {
int x;
};
template <typename Type>
class has_member_x
{
class yes { char m;};
class no { yes m[2];};
struct BaseMixin
{
int x;
};
struct Base : public Type, public BaseMixin {};
template <typename T, T t> class 开发者_如何学GoHelper{};
template <typename U>
static no deduce(U*, Helper<void (BaseMixin::*)(), &U::x>* = 0);
static yes deduce(...);
public:
static const bool result = sizeof(yes) == sizeof(deduce((Base*)(0)));
};
int main() {
BOOST_STATIC_ASSERT(has_member_x<int>::result);
BOOST_STATIC_ASSERT(has_member_x<Vector>::result);
}
When I try to compile this it fails with the following error.
error: base type ‘int’ fails to be a struct or class type
Is there a way that this can be done in either c++ or c++0x?
After fixing a bug in the original has_member_x
class, and adding specialization for class
types as it was suggested by others the final working version looks like this:
#include <type_traits>
template <typename Type, bool Enabled = std::is_class<Type>::value>
class has_member_x
{
public:
static const bool result = false;
};
template <typename Type>
class has_member_x<Type, true>
{
class yes { char m;};
class no { yes m[2];};
struct BaseMixin
{
int x;
};
struct Base : public Type, public BaseMixin {};
template <typename T, T t> class Helper{};
template <typename U>
static no deduce(U*, Helper<int BaseMixin::*, &U::x>* = 0);
static yes deduce(...);
public:
static const bool result = sizeof(yes) == sizeof(deduce((Base*)(0)));
};
You can use boost::enable_if and boost::type_traits, specifically boost::is_integral or boost::is_class for this.
Try this(I have not tested it, but this should give you the idea.):
struct Vector {
int x;
};
template <typename Type, typename Enabled = void>
class has_member_x
{
public:
static const bool result = false;
};
template <typename Type, typename Enabled = boost::enable_if<boost::is_class<Type> >::type >
class has_member_x
{
class yes { char m;};
class no { yes m[2];};
struct BaseMixin
{
int x;
};
struct Base : public Type, public BaseMixin {};
template <typename T, T t> class Helper{};
template <typename U>
static no deduce(U*, Helper<void (BaseMixin::*)(), &U::x>* = 0);
static yes deduce(...);
public:
static const bool result = sizeof(yes) == sizeof(deduce((Base*)(0)));
};
int main() {
BOOST_STATIC_ASSERT(has_member_x<int>::result);
BOOST_STATIC_ASSERT(has_member_x<Vector>::result);
}
精彩评论