【问题标题】:SFINAE to check the existence of operators (without decltype)SFINAE 检查是否存在操作符(没有 decltype)
【发布时间】:2014-10-07 12:58:02
【问题描述】:

我正在尝试做我学校的一个旧项目,它处理 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 的丑陋表达式应该用于类型定义,我试图 typedef 它但编译器对我尖叫。

我没有得到所有东西,因为我对此很陌生,我知道有一些方法可以使用 decltype 运算符简化它,但该项目的目标是在 C++98 中完成,如果我以后能找到一些该类型的代码,它可能会很有用。

【问题讨论】:

  • 提示:你需要把static_cast这一行放到一个会导致替换失败的地方,而不是编译错误。
  • SFINAE 在学校教授?我什至没有。
  • 这实际上取决于expression SFINAE,它只是……有点……C++98的一部分。
  • @Cicada - 不要惊讶,它是“一个老项目”:)
  • 非常感谢大家!所以我放错了这条线,这很难理解..但我会努力的! @SChepurin 是的,它已经 2 岁了,他们仍然把它交给学生 AFAIK。

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


【解决方案1】:
#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

【讨论】:

    【解决方案2】:
    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

    【讨论】:

      猜你喜欢
      • 2011-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多