3

考虑类似...

template<typename T>
class Vector {
  ...
  bool operator==( const Vector<float> &rhs ) {
    // compare and return
  }

  bool operator==( const Vector<T> &rhs ) {
    // compare and return
  }
  ...
 };

请注意专业化如何高于非专业化版本。如果我将专业版本放在非专业版本之下Vector<float>, == 比较是否仍能按预期工作?出于某种原因,我想我记得读过,如果您在这种情况下将专业化放在下面,那么当编译器查看标头时,它将首先看到默认值,看看它是否有效,然后使用它。

4

2 回答 2

7

您的示例代码不是专门化的,而是重载的。顺序确实很重要(虽然不在您的代码中),因为在 C++ 中知道函数之前需要声明函数。因此,如果一个重载调用另一个重载,或者如果中间的另一个函数调用重载集,则调用可能会在某个不需要的地方结束。您的示例代码有效且常见。

出于某种原因,我想我记得读过,如果您在这种情况下将专业化放在下面,那么当编译器查看标头时,它将首先看到默认值,看看它是否有效,然后使用它。

您正在考虑以下规则

如果模板、成员模板或类模板的成员是显式特化的,则应在第一次使用该特化之前声明该特化,这将导致发生隐式实例化,在每个翻译单元中出现这种使用; 不需要诊断。

我忍不住在这里引用标准中关于专业化的搞笑说法

根据显式特化声明的相对定位及其在翻译单元中的实例化点(如上文和下文指定),可能会影响程序是否格式正确。编写专业时,请注意其位置;或者让它编译将是一种试炼,以点燃它的自焚。

于 2010-08-21T01:38:13.047 回答
-3

正如所写,我相信你有一个错误。你没有专门化 operator==,你正在重载它。不允许您重载这样的模板参数。

如果你的方法是一个自由函数,那么你可以专门化它。例如

template <typename T>
void Foo(Vector<T> x) {
   std::cout << "x" << std::endl;
}
template <>
void Foo(Vector<float> y) {
   std::cout << "y" << std::endl;
}

...
Vector<int> intVec;
Vector<float> floatVec;
Foo(intVec); //prints x
Foo(floatVec); //prints y

在这种情况下,如果您使用 Foo 调用Vector<float>,您将调用专用版本。

秩序在某种程度上很重要。首先,编译器总是偏爱一种特化而不是非特化形式(如果可用)。之后,编译器将尝试按顺序实例化每个函数。如果它可以成功编译它,则将使用该专业化。如果不能,它将继续下一个。这个原则称为替代失败不是错误(SFINAE)。 http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error有更详细的描述。

于 2010-08-20T22:44:51.067 回答