【问题标题】:SFINAE To detect non-member function existenceSFINAE 检测非成员函数的存在
【发布时间】:2011-03-23 11:37:13
【问题描述】:

是否有人知道根据是否定义了非成员方法来专门化模板的方法?我知道如果存在成员函数,有很多方法可以专门化,但我从未见过非成员示例。具体问题是,如果为 T 定义了 operator

template <typename T>
typename enable_if< ??? ,std::ostream &>::type operator<<( std::ostream & os, const shared_ptr<T> & ptr )
{
  if(ptr)
   return os << *ptr;
  else
   return os << "<NULL>";
}

template <typename T>
typename disable_if< ??? ,std::ostream &>::type operator<<( std::ostream & os, const shared_ptr<T> & ptr )
{
  if(ptr)
   return os << static_cast<intptr_t>( ptr.get() );
  else
   return os << "<NULL>";
}

编辑:对于后代,这是可行的解决方案。注意 boost::shared_ptr 已经有一个默认的 operator

template <typename T>
typename boost::enable_if_c< boost::is_reference<decltype(*static_cast<std::ostream *>(0) << *static_cast<T *>(0) )>::value, std::ostream &>::type operator<<( std::ostream & os, const boost::shared_ptr<T> & ptr )
{
  if(ptr)
   return os << *ptr;
  else
   return os << "<NULL>";
}

【问题讨论】:

  • This solution 可能对您有所帮助。这是解决问题的不同方法,但结果相同。如果未定义运算符,它将转到通用输出函数,您可以在其中做任何您想做的事情。不作为答案发布,因为它没有回答标题问题,但我推荐这个。
  • 您很少会发现将流插入和提取运算符实现为成员函数的类,因为需要作为左操作数的是 stream,而不是类.
  • 好电话 Rob。我没想到这一点。
  • 只想说,我认为您不需要任何 enable_if 东西。我认为它只适用于 decltype。
  • DeadMG,在这种情况下你肯定是对的,但我认为这是我们想要有条件地实例化的函数(operator)和我们正在使用的函数的幸运结果查询具有相同返回值的 (operator

标签: c++ sfinae


【解决方案1】:

如果你使用的是 C++0x,你可以简单地使用 decltype。

template<typename Char, typename CharTraits, typename T>
        decltype(
            *(std::basic_ostream<Char, CharTraits>*)(nullptr) << *(T*)(nullptr)
        )

如果不能输出 T,那肯定会导致替换失败。您可能可以在 C++03 中做类似的事情,但我不确定如何。

编辑:刚刚意识到 decltype 表达式实际上不会产生真或假值并且不会编译。但你明白了。试试这个。

【讨论】:

  • 太棒了!那行得通。为了后代,我将在上面包含我的完整代码。
  • 这根本没有提供一个通用的解决方案。
猜你喜欢
  • 2016-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多