SFINAE to check for the existence of statements (without decltype)

I am trying to make an old project of my school that deals with metaprogramming in C ++ 98. The part that I am struggling with is with SFINAE.

Subject says that I should check if the operator<<flow object works with another object using this structure:

template<typename Stream, typename Object>
struct IsPrintable;

It says that I should write a strange line with "two null references", I think it should look like this:

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

It works when the statement is supported, but does not compile when it is not. I can't figure out where I am failing, here is the file:

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, , .

, , , decltype, - ++ 98, , .

+4
2
#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

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

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

    template <typename U>
    static yes& isPrintable(Test<sizeof(*(static_cast<Flux*>(NULL)) << *(static_cast<U*>(NULL)))>* = 0);

    template <typename> static no& isPrintable(...);
public:
    static const bool value = sizeof(isPrintable<Object>(0)) == sizeof(yes);
};

+3

All Articles