[英]Using SFINAE gives different results on GCC and Clang
我正在學習如何使用SFINAE。 我正在嘗試使用它來根據對象中serialize()
函數的存在來選擇函數實現。
這是我用來確定的代碼,如果類型定義了serialize()函數:
template <typename T>
class HasSerialize {
private:
typedef char yes[1];
typedef char no[2];
template <typename C> static yes& test(char[sizeof(&C::serialize)]) ;
template <typename C> static no& test(...);
public:
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
但是,它似乎在GCC和Clang上給出了完全相同的結果。 假設以下代碼:
template<bool T>
class NVPtypeSerializer {
public:
template<typename C>
static xmlChar* serialize(C value) {
// serize() is not available
}
};
template<>
struct NVPtypeSerializer<true> {
public:
template<typename T>
static xmlChar* serialize(T value) {
return value.serialize();
}
};
這被稱為:
foo = NVPtypeSerializer<HasSerialize<Bar>::value >::serialize(value);
類Bar
沒有serialize()
函數。 這段代碼在Clang 3.1下編譯得很好,但是在GCC 4.7.1上我得到以下錯誤:
error: ‘class Bar’ has no member named ‘serialize’
如果我將struct NVPtypeSerializer<true>
更改為struct NVPtypeSerializer<false>
它可以在GCC上編譯,但Clang會出現以下錯誤:
error: no member named 'serialize' in 'Bar'
問題出在哪兒? 它在我的代碼中嗎? 我希望盡可能地使代碼具有可移植性。
這真的是代碼test(char[sizeof(&C::serialize)])
? 請注意,接受數組的函數聲明實際上聲明了一個帶有指針的函數:
template <typename C> static yes& test(char[sizeof(&C::serialize)]) ;
這實際上意味着:
template <typename C> static yes& test( char* );
順便提一下,是什么讓你的調用test<C>(0)
編譯。 我不認為這是檢測功能是否存在的正確方法。 關於如何使用SFINAE檢測類中是否存在成員/成員函數的Google。
(一個簡單的解決方案是添加一個額外的默認參數 - 提供了一個啟用了C ++ 11的編譯器:
template <typename C, std::size_t = sizeof(&C::serialize)>
static yes& test(int) ;
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.