2014-10-07 2 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

+2

SFINAE преподается в школе? Я даже не знаю. –

+0

Это на самом деле зависит от [выражения SFINAE] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html), который является только ... видом ... часть C++ 98. –

ответ

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

Смежные вопросы