C++ 作为友元函数的运算符重载

C++ 作为友元函数的运算符重载,c++,templates,operator-overloading,C++,Templates,Operator Overloading,我创建了一个模板类,并希望重载操作符+(多次)。我是这样做的 template <typename T> class Polynomial; template <typename T> const Polynomial<T> operator +(const Polynomial<T>& poly, const T& scalar); .... template <typename T> class Polynom

我创建了一个模板类,并希望重载操作符+(多次)。我是这样做的

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
}
模板类多项式;
模板
常数多项式算子+(常数多项式与多边形,常数T与标量);
....
模板
类多项式{
....
公众:
....
多项式运算符+(常数多项式和其他)常数{
//推进
}
friend常数多项式算子+(常数多项式与多边形,常数T与标量);
};
模板
常量多项式运算符+(常量多项式和多边形,常量T和标量){
//实施
}
但是,我得到了以下错误(对应于以“friend”开头的行)

问题2.cpp:282:45:错误:将“运算符+”声明为非函数
问题2.cpp:282:45:错误:应为“;”在成员声明末尾

问题2.cpp:282:47:错误:在“之前应为非限定id当您将函数标记为friend时,必须具有相同的定义,这包括上面使用的另一类型的模板,而不是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)
{
    //...
}

Raxvan。

将函数标记为friend时,必须具有相同的定义,这包括上面使用的另一种类型的模板,而不是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)
{
    //...
}

Raxvan。

您的
操作符+
是一个函数模板,要使其成为朋友,您需要声明它完全包括模板参数,但是使用不同的模板参数,例如:

#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>();
}
#包括
模板类多项式;
模板
常数多项式算子+(常数多项式与多边形,常数T与标量);
模板
类多项式{
公众:
多项式运算符+(常数多项式和其他)常数{

std::cout您的
操作符+
是一个函数模板,要使其成为朋友,您需要声明它完全包含模板参数,但是使用不同的模板参数,例如:

#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>();
}
#包括
模板类多项式;
模板
常数多项式算子+(常数多项式与多边形,常数T与标量);
模板
类多项式{
公众:
多项式运算符+(常数多项式和其他)常数{

std::cout问题很微妙。您的语法非常接近于 正确。我认为你的朋友声明应该是:

friend Polynominal<T> const operator+<T>( ... );
(请注意,所定义的函数不是模板,而是 单独的重载非模板函数,每个函数一个
多项式的实例化
。但结果最终是 相同。)

在这种情况下,您可能需要一个成员函数, 由
操作符+
函数调用,该函数将执行实际的
工作;您不需要太多这样直接内联的代码。

问题很微妙。您的语法非常接近于 正确。我认为你的朋友声明应该是:

friend Polynominal<T> const operator+<T>( ... );
(请注意,所定义的函数不是模板,而是 单独的重载非模板函数,每个函数一个
多项式的实例化
。但结果最终是 相同。)

在这种情况下,您可能需要一个成员函数, 由
操作符+
函数调用,该函数将执行实际的
工作;您不希望有太多的代码像这样直接内联。

尖括号是什么?
友元常量多项式运算符+***(
,丢失它们…它们是必需的,因为模板函数更新了答案;运算符尖括号是什么?
友元常量多项式运算符+****(
,丢失它们…它们是必需的,因为它的模板函数更新了答案;操作员感谢,这很有效!但是,我不明白为什么。你能通过回答修改后的问题来解释吗?但在我的情况下,这两个函数都是模板函数(它们有模板参数)谢谢,这很有效!但是,我不明白为什么。你能通过回答修改后的问题来解释吗?但在我的例子中,两个函数都是模板函数(它们都有模板参数)谢谢,成功了!但是,我不明白为什么。你能通过回答修改后的问题来解释吗?但是,这将使所有可能的
操作符+
(对于每个可能的
U
)一个
多项式
的朋友,而只有
T
操作符+
需要成为朋友。尽管我同意这在实践中可能不是他的问题。根据你的说法,你需要
朋友常量多项式操作符+(常量多项式&,常量T&);
仅使特定的
T
版本成为
多项式的朋友。这类似于OP的第一次尝试,但在
函数名之后的
T
中增加了一个
T。这是错误的。这会使模板的所有实例化
操作符+
成为所有实例化的朋友de>多项式
,这不是(我认为)想要什么。@詹姆斯坎兹,我也不确定,但是,我想不出这有什么坏处?也许你可以扩展你的答案来指出坏处…谢谢,这很有效!但是,我不明白为什么。你能通过回答修改过的问题来解释吗?不过,这会使所有的
操作都可行或者+
(对于所有可能的
U
)是
多项式的朋友,而只有
T
操作符+
需要是朋友。虽然我同意这在实践中可能不是他的问题。根据你的说法,你需要
朋友常量多项式操作符+(常量多项式&,常量T&);
仅使特定的
T
版本成为
多项式的朋友。这类似于OP的第一次尝试,但在
函数名之后的
T
中增加了一个
T。这是错误的。这会使模板的所有实例化
操作符+
成为所有实例化的朋友de>多项式
,这不是(我认为)想要的。@JamesKanze,看,我也不确定这一点,但是,我想不出
friend Polynominal<> const operator+<T>( ... );
template <typename T>
const Polynomial<T> operator+(const Polynomial<T>& poly, const T& scalar);
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 )
    {
        //  ...
    }
}