我创建了一个模板类,并希望重载运算符+(多次)。我这样做是按照以下方式进行的
template <typename T> class Polynomial;
template <typename T>
const Polynomial<T> operator +(const Polynomial<T>& poly, const T& scalar);
....
template <typename T>
class Polynomial {
....
public:
....
Polynomial operator +(const Polynomial& other) const {
// impelementation
}
friend const Polynomial<T> operator + <> (const Polynomial<T>& poly, const T& scalar);
};
template <typename T>
const Polynomial<T> operator +(const Polynomial<T>& poly, const T& scalar) {
// implementation
}
但是,我收到以下错误(对应于以'friend'开头的行)
problem2.cpp:282:45: error: declaration of ‘operator+’ as non-function
problem2.cpp:282:45: error: expected ‘;’ at end of member declaration
problem2.cpp:282:47: error: expected unqualified-id before ‘<’ token
按照Raxvan的建议,我改变了代码
模板类多项式;
template <typename T>
const Polynomial<T> operator +(const Polynomial<T>& poly, const T& scalar);
template <typename T>
ostream& operator <<(ostream& out, const Polynomial<T>& other);
....
template <typename T>
class Polynomial {
....
public:
....
friend ostream& operator << <> (ostream& out, const Polynomial<T>& other);
Polynomial operator +(const Polynomial& other) const {
// impelementation
}
template <typename NOT_T>
friend const Polynomial<NOT_T> operator +(const Polynomial<NOT_T>& poly, const NOT_T& scalar);
};
template <typename T>
ostream& operator <<(ostream& out, const Polynomial<T>& other) {
// implementation
}
template <typename T>
const Polynomial<T> operator +(const Polynomial<T>& poly, const T& scalar) {
// implementation
}
在此代码中,我没有运算符&lt;&lt;的问题就像我在操作员+上一样。任何人都可以解释这种干涉吗?
答案 0 :(得分:2)
问题很微妙。你的语法非常接近 正确。我认为你的朋友声明应该是:
friend Polynominal<T> const operator+<T>( ... );
但VC ++和g ++都接受:
friend Polynominal<> const operator+<T>( ... );
当他们看到声明时:
template <typename T>
const Polynomial<T> operator+(const Polynomial<T>& poly, const T& scalar);
(我无法在标准中找到任何可以证明这一点的理由, 但既然VC ++和g ++都这样做,我想这就是它 我错过了。)
其中存在问题。命名空间的声明
内部定义隐藏operator+
的范围。该
编译器抱怨,因为它找到了operator+
(in
类定义)本身不是模板(虽然它是
类模板的成员)。
如果您对operator<<
没有问题,那是因为
你没有一个同名的成员函数。
有几种方法可以解决这个问题。最简单的是
可能会成为所有operator+
朋友。或者不是:
最常见的方法是实现operator+
operator+=
的条款(在所有情况下都应该是成员)。
在这种情况下,operator+
不一定是朋友。
或者你根本不让operator+
成为一个模板,但要确定它
在您的班级模板中:
template <typename T>
class Polynomial
{
friend Polynomial operator+( Polynomial const& lhs, Polynomial const& rhs )
{
// ...
}
friend Polynomial operator+( Polynomial const& lhs, T const& rhs )
{
// ...
}
friend Polynomial operator+( T const& lhs, Polynomial const& rhs )
{
// ...
}
}
(请注意,所定义的功能是不是模板,但是
单独重载的非模板函数,每个函数一个
实例化Polynomial
。但结果最终成了
相同。)
在这种情况下,您可能希望拥有一个成员函数,
由operator+
函数调用,这将实际执行
工作;你不需要像这样直接内联的太多代码。
答案 1 :(得分:1)
当您将某个功能标记为朋友时,您必须具有相同的定义,这包括上面使用的另一种类型的模板,而不是T
template <typename T> class Polynomial;
template <typename T>
const Polynomial<T> operator +(const Polynomial<T>& poly, const T& scalar);
template <typename T>
class Polynomial {
public:
template < class NOT_T> //must respect the deffinition from above
friend const Polynomial<NOT_T> operator + (const Polynomial<NOT_T>& poly, const NOT_T& scalar);
};
template <typename T>
const Polynomial<T> operator +(const Polynomial<T>& poly, const T& scalar)
{
//...
}
编辑:
为了简化说明,我已将功能更改为foo
和bar
以说明声明的差异:
template <typename T> class Polynomial;
template <typename T>
void bar(const Polynomial<T>& );
void foo(const Polynomial<float> & );//foo for speciffic float
template <typename T>
class Polynomial {
public:
template <typename> //this is also valid declaration;
friend void bar(const Polynomial<T> & );
//it just has to have template because it's a template functions declaration
//not a valid declaration:
//friend void bar <> (const Polynomial<T> & );
//this declaration has no template;
//it refers to a foo function specific to Polynomial<T> type
//so if you use Polynomial<float> there must be a foo for floats
friend void foo(const Polynomial<T> &);
};
template <class T>
void bar(const Polynomial<T>&)
{
}
void foo(const Polynomial<float> &)
{
}
void main()
{
Polynomial<float> pf;
Polynomial<int> pi;
foo(pi);//error since there is not **foo** declared for int
foo(pf);//ok; we have **foo** for Polynomial<float>
bar(pf);
bar(pi);//both ok since bar is templated function;
}
Raxvan。
答案 2 :(得分:1)
您的operator+
是一个功能模板,为了使其成为朋友,您需要完全声明它包含模板参数,但是使用不同的模板参数,例如:
#include <iostream>
template <typename T> class Polynomial;
template <typename T>
const Polynomial<T> operator +(const Polynomial<T>& poly, const T& scalar);
template <typename T>
class Polynomial {
public:
Polynomial operator +(const Polynomial& other) const {
std::cout << "inline +" << std::endl;
}
// Here introduce a different type to indicate that this is a template...
template <typename U>
friend const Polynomial<U> operator + (const Polynomial<U>& poly, const U& scalar);
};
template <typename T>
const Polynomial<T> operator +(const Polynomial<T>& poly, const T& scalar) {
std::cout << "friend +" << std::endl;
}
int main(void)
{
Polynomial<int> f;
f = f + 1;
f = f + 1.; // this fails
f = f + Polynomial<int>();
}