簡體   English   中英

使用SFINAE在GCC和Clang上給出了不同的結果

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM