模板专业化不明确

The*_*ake 0 c++ templates template-meta-programming

又一个模板问题!我正在尝试获取一个模板方法,如果它有一个运算符<<的重载,它将输出一个对象.我几乎都在工作,并实现了一个enable_if,以使g ++为每种类型的对象选择预期的专业化.

事情是,对于非重载对象,它工作得很好.但是对于一个超载的,我的两个专业都是g ++的合理选择,而不是编译它输出一个模糊的重载错误.

这是代码:

template<typename T>
  static void   Print(Stream& out, T& param, typename enable_if<CanPrint<T>::value>::type = 0)
  {
    out << param;
  }

  template<typename T>
  static void   Print(Stream& out, T& param)
  {
    out << "/!\\" << typeid(param).name() << " does not have any overload for <<.\n";
  }
Run Code Online (Sandbox Code Playgroud)

我理解为什么这样的事情是模棱两可的.然而,我想不出一种方法可以让它变得更加明显......我如何让编译器明白第二次重载只有在第一次不能被选中时才会被选中?

Nod*_*ode 8

你会得到歧义,因为在这两种情况下你都有一个函数,它接受一个流,然后你的类型T作为前两个参数.这有效:

#include <iostream>
#include <boost/utility/enable_if.hpp>
#include <typeinfo>

template <class T>
struct CanPrint { enum { value = 0 }; };

template <>
struct CanPrint<int> { enum { value = 1 }; };

template<typename T>
typename boost::enable_if<CanPrint<T>, void>::type 
    Print(std::ostream& out, T& param)
{
    out << param << std::endl;
}

template<typename T>
typename boost::disable_if<CanPrint<T>, void>::type 
    Print(std::ostream& out, T& param)
{
    out << "/!\\" << typeid(param).name() << " does not have any overload for <<.\n";
}

int main()
{
    int i = 1;
    double d = 2;

    Print(std::cout, i);
    Print(std::cout, d);
}
Run Code Online (Sandbox Code Playgroud)

  • @ The-Snake真正的修复是使用`disable_if`来从重载集中删除'错误'的重载. (2认同)