3

有没有人知道根据是否定义了非成员方法来专门化模板的方法?我知道如果存在成员函数,有很多方法可以专门化,但我从未见过非成员示例。具体问题是,如果为 T 定义了 operator<<,则为 shared_ptr 专门化 operator<< 以应用 operator<<,否则仅打印指针位置。如果所有类都将 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<< 输出地址,所以 disable_if 是不必要的。由于 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>";
}
4

1 回答 1

2

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

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

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

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

于 2010-07-30T22:08:10.917 回答