2011-08-01 35 views
0

我需要检查并查看给定的类型是否有成员变量。但是,如果给出的类型不是类或结构,则会出现编译器错误。使用模板来检查不工作的成员变量int

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 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); 
} 

当我尝试编译它失败,并出现以下错误。

error: base type ‘int’ fails to be a struct or class type

有没有一种方法可以在C++或C++ 0x中完成?

+1

关闭我的头顶,我的第一个想法是专门为非类类型的'has_member_x'。 –

+0

为什么不检查std :: numeric_limits <>是否专门针对您的类型T?如果是,假设它没有成员'x'。或者为内建函数编写你自己的专业化版本,比如'template <> class has_member_x {public:static const bool result = false; }'。 – Sjoerd

回答

1

has_member_x类修复bug,并增加专门用于class类型后,因为有人建议其他人的最终工作版本看起来像这样:

#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))); 
}; 
1

你可以使用boost :: enable_if和boost :: type_traits,特别是boost :: is_integral或boost :: is_class。

试试这个(我没有测试过,但是这应该给你的想法。):

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); 
} 
+1

想法很好,执行不了,看这里:http://ideone.com/v8JBH –

+0

谢谢基因:)。我可以更新该帖子并信用你,或者你想继续并发布解决方案。 – user258808

+0

我失明了吗?为什么这是失败的? :http://ideone.com/hgI5k –