我对模板专业化略显困惑。
我有课程Vector2
,Vector3
,其中包含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;
}
这个编译很好,适用于Vector2
和Vector3
。但是,我想说我希望{{1}有一个更高效的“+”操作我想让它按以下方式行事(使用模板专业化):
Vector2
这对我来说很好看,但不幸的是,将这两个代码紧接在一起使得代码无法编译
(链接器说错误template<> const Vector2 operator+(const Vector2& v1, const Vector2& v2) {
return Vector2(v1.x() + v2.x(), v1.y() + v2.y());
}
)
我的错误是什么?我哪里出错?
谢谢。
答案 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
}