2014-10-07 74 views
4

我正在嘗試做一個我的學校的舊項目,它處理C++ 98中的元編程。 我正在努力的部分是關於SFINAE。SFINAE檢查運算符的存在(沒有decltype)

主題說我應該檢查是否是流對象,通過使用一個結構類似這樣的另一個對象之間operator<<作品:

template<typename Stream, typename Object> 
struct IsPrintable; 

它說我應該寫一個奇怪符合「兩空引用」,我想這應該是這樣的:

sizeof(*(static_cast<Stream *>(NULL)) << *(static_cast<Object *>(NULL))) 

當支持運營商它的工作原理,但是當它是不是不能編譯。 我想不通,我失敗了,這裏的文件:

template<typename Flux, typename Object>                                                  
struct IsPrintable 
{ 
    typedef char yes[1]; 
    typedef char no[2]; 

    template<size_t N> 
    struct Test 
    { 
    typedef size_t type; 
    }; 

    template<typename U> 
    static yes &isPrintable(U * = 0); 

    template<typename> 
    static no &isPrintable(...); 

    static const bool value = sizeof(isPrintable<Test<sizeof(*(static_cast<Flux *>(NULL)) << *(static_cast<Object *>(NULL)))> >(0)) == sizeof(yes); 

}; 

主題明確地說,使用類採取的size_t作爲參數,並且該isPrintable方法應採取一個NULL指針這個類實例。此外,使用static_cast的醜陋表達式應該用於類型定義,我嘗試過typedef,但編譯器向我尖叫。

我沒有得到一切,因爲我對此很陌生,我知道有一種方法可以簡化與decltype運算符,但該項目的目標是在C++ 98中執行此操作,並且如果我稍後找到某種類型的代碼,它可能會很有用。

+4

提示:你需要把'static_cast'線到一個地方,就會造成失敗的替代,而不是一個編譯錯誤。 – Angew 2014-10-07 13:01:13

+2

SFINAE在學校任教?我甚至沒有。 – 2014-10-07 13:18:16

+0

這實際上取決於[表達SFINAE](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html),它只是......種類...屬於C++ 98的一部分。 – 2014-10-07 13:44:48

回答

6
#include <cstddef> 

template<typename Flux, typename Object>                                                  
struct IsPrintable 
{ 
    typedef char yes[1]; 
    typedef char no[2]; 

    template <std::size_t N> 
    struct SFINAE {}; 

    template <typename F, typename O> 
    static yes& isPrintable(SFINAE<sizeof(*static_cast<F*>(NULL) << *static_cast<O*>(NULL))>* = 0); 

    template <typename F, typename O> 
    static no& isPrintable(...); 

    static const bool value = sizeof(isPrintable<Flux, Object>(NULL)) == sizeof(yes); 
}; 

DEMO