【问题标题】:template deduction evaluates to overload of identical functions模板推导计算为相同函数的重载
【发布时间】:2016-12-08 23:45:58
【问题描述】:

我有以下课程:

template <typename T>
struct Foo {
  void bar(double val);
  void bar(T val);
  T m_val;
};

现在的问题是,如果我实例化一个 Foo&lt;double&gt; 类型的对象,我会得到两个具有相同签名的重载函数。

有什么办法解决吗?

我的问题是我确实需要处理 val 类型为 double 特殊的情况。此外,非双精度类型的bar 参数没有共同的超类。

【问题讨论】:

  • 当你实例化一个Foo&lt;double&gt; 时你想要什么行为?您希望它使用bar 的定义和T 作为参数,还是使用double 的定义?
  • @Jon McClung,感谢您的评论。我想用双倍的。
  • 使用 enable_if 禁用 double 的泛型
  • @严舟好主意!

标签: c++ c++11 templates overloading


【解决方案1】:

另一种方法是使用 SFINAE 禁用功能:

#include <iostream>
#include <string>
#include <vector>

template <typename T>
struct Foo {
 void bar(double val){
     std::cout << "bar(double)\n";
 }

  template<class Y=T>
  typename std::enable_if<!std::is_same<Y, double>::value>::type  
  bar(T val){
      std::cout << "bar(T)\n";
      }

  T m_val;
};

int main()
{
  Foo<double> dd;
  dd.bar(1.0);

  Foo<std::string> dd2;
  dd2.bar("asds");
  dd2.bar(1.0);
}

[编辑]

正如 W.F 在评论中指出的那样,这里不需要 enable_if,将 bar(T) 设为模板成员函数就足以消除歧义:

template<int=0>
void bar(T val){
  std::cout << "bar(T)\n";
}

【讨论】:

  • 我认为单独制作 bar 模板会使编译器更喜欢非模板重载 - 实际上这里不需要使用 enable_if...
  • @marcinj 我想我不明白 W.F.评论,但为什么我们需要 template
  • @user695652 有返回类型,enable_if 默认为void
【解决方案2】:

您可以创建模板专业化。在模板类或函数的专门化中,您为特定类型定义独特的行为。例如:

template<typename T>
struct Foo {
   void bar(T);
   T m_val;
}

template <>
struct Foo<double> {
   void bar(double);
   double m_val;
};

或者你可以只为这种情况专门化一个函数:

template <>
void Foo<double>::bar(double); 

现在当您执行以下操作时:

int main() {
   Foo<double> ob1;
   Foo<int> obj2;

   obj1.bar(1,3);
   obj2.bar(45);
   return 0;
}

obj1.bar 从特化中调用 bar 函数。

【讨论】:

  • 感谢您的回答。您能否将其扩展一点,我不明白如何在您的方法中使用非双精度值调用bar
  • 我希望它能满足你的问题,如果没有,请随时询问
猜你喜欢
  • 2012-12-03
  • 1970-01-01
  • 2022-08-19
  • 2019-10-22
  • 1970-01-01
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多