2011-08-01 70 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 –