C ++基本模板问题

时间:2010-07-15 12:04:12

标签: c++ templates specialization

我对模板专业化略显困惑。

我有课程Vector2Vector3,其中包含operator+=(按以下方式定义)。

   Vector2& operator+=(const Vector2& v) {

      x() += v.x(), y() += v.y();

      return *this;
   }

现在我想添加泛型添加行为并说出类似的内容:

template <typename V> const V operator+(const V& v1, const V& v2) {
   return V(v1) += v2;
}

这个编译很好,适用于Vector2Vector3但是,我想说我希望{{1}有一个更高效的“+”操作我想让它按以下方式行事(使用模板专业化)

Vector2

这对我来说很好看,但不幸的是,将这两个代码紧接在一起使得代码无法编译

(链接器说错误template<> const Vector2 operator+(const Vector2& v1, const Vector2& v2) { return Vector2(v1.x() + v2.x(), v1.y() + v2.y()); }

我的错误是什么?我哪里出错?

谢谢。

3 个答案:

答案 0 :(得分:7)

如果特化是在头文件中,那么你需要声明它inline以允许它包含在多个编译单元中。

请注意,您实际上并不需要模板专业化;一个简单的重载也会做同样的事情。

答案 1 :(得分:3)

把这个

template<> const Vector2 operator+(const Vector2& v1, const Vector2& v2);
标题文件中的

template<> const Vector2 operator+(const Vector2& v1, const Vector2& v2) {
   return Vector2(v1.x() + v2.x(), v1.y() + v2.y());
}

.cpp 文件中。

答案 2 :(得分:3)

我不确定你是否想要遵循这条道路。您定义为模板的operator+将匹配任何和所有类型,可能会产生冲突。为什么不为每个向量提供一个简单的非模板operator+

还有其他风格问题:

Vector2& operator+=(const Vector2& v) {
   x() += v.x(); // you don't need operator, here and it might
                 // be confusing if you don't have operator, priorities clear
   y() += v.y();
   return *this;
}

此外:

// This should not be a template!!!
template <typename V> const V operator+(V v1, const V& v2) {
   return v1 += v2;
}

在某些情况下,如果上面定义了operator+(如果第一个参数是临时的),则编译器可以忽略该副本,而它不能用您的定义忽略该副本。

您定义的operator+问题是编译器会尝试将其与任何类型一起使用:

struct non_sumable {};
int main() {
   non_sumable a,b;
   a + b;           // matches the template, tries to instantiate
                    // compiler error says that non_sumable does not 
                    // have operator+=, which might be confusing
}