SFINAE检测非成员函数存在 [英] SFINAE To detect non-member function existence

查看:120
本文介绍了SFINAE检测非成员函数存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人知道根据是否定义非成员方法专门化模板的方法吗?我知道有很多方法专门化如果一个成员函数存在,但我从来没有见过一个非成员的例子。具体问题是,为shared_ptr应用运算符<<如果操作符<定义为T,否则打印纯粹的指针位置。如果所有类定义的运算符<<作为成员,但不幸的是许多使用自由功能。我想象如下:

Does anybody know of a method for specializing a template depending on whether a non-member method is defined? I know there are numerous ways for specializing if a member function exists, but I've never seen a non-member example. The specific problem is specializing the operator<< for shared_ptr to apply the operator<< if the operator<< is defined for T, and printing the mere pointer location otherwise. It would be great if all classes defined operator<< as a member, but unfortunately many use free functions. I'm imagining something like the following:

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已经有一个默认的操作符<<输出地址,因此disable_if是不必要的。由于操作员<<返回一个引用,这个工程。对于一般情况,我怀疑这将被定制以反映所讨论的函数的返回类型。

For posterity, here was the working solution. Note that boost::shared_ptr already has a default operator<< that outputs the address, so the disable_if is unnecessary. Since the operator<< returns a reference, this works. For the general case I suspect this would have to be tailored to reflect the return type of the function in question.

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


推荐答案

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

If you are using C++0x, you could simply use decltype.

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

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

That'll certainly cause a substitution failure if a T cannot be output. You could probably do something similar in C++03, but I'm not sure how.

编辑:只是意识到decltype表达式实际上不产生真或false值,不会编译。但你得到的图片。试试这个。

Just realised that the decltype expression doesn't actually produce a true or false value and won't compile. But you get the picture. Try this.

这篇关于SFINAE检测非成员函数存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆