SFINAE检查运营商的存在(没有decltype)

时间:2014-10-07 12:58:03

标签: c++ metaprogramming sfinae c++98

我正在尝试为我的学校做一个旧项目,它涉及C ++ 98中的元编程。 我正在努力反对的部分是关于SFINAE。

主题说我应该通过使用这样的结构来检查流对象和另一个对象之间的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的丑陋表达式应该用于类型定义,我试着键入它但是编译器对我尖叫。

我没有得到所有内容,因为我对此很新,我知道有一些方法可以使用decltype运算符来简化它,但项目的目的是在C ++中完成它98,如果我稍后找到那种类型的代码,它会很有用。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:3)

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);
};

Live example