模板运算符看似模糊不清

Bol*_*pat 6 c++ templates header operators c++11

这不是重复的.我查了很多答案,常见问题解答等等.没有什么告诉我新闻.这是简化的代码.获取并解释错误是最小的.

/*** Polynomial.hpp ********************************************************/

namespace Modulus
{
// Forward declaration of the types and non-inline template friend functions.

template <typename T>
    class Polynomial;

template <typename T>
    Polynomial<T>  operator +
        (Polynomial<T> const & p,
         Polynomial<T> const & q);
}

namespace Modulus
{

template <typename T>
class Polynomial
{
public:
    Polynomial() { }

    // [!] when you comment this in, you get the error.
    //Polynomial      operator +      () const { return *this; }

    friend Polynomial operator + <> (Polynomial const & p,
                                     Polynomial const & q);
};

} // namespace

// Template: include .cpp file.
   //#include "Polynomial.cpp"
///^ It is commented out, for compiling in one file.


/*** Polynomial.cpp ********************************************************/

namespace Modulus
{

template <typename T>
Polynomial<T>
    operator + (Polynomial<T> const & p,
                Polynomial<T> const & q)
{
    return Polynomial<T>();
}

} // namespace


/*** main.cpp **************************************************************/


//#include "Polynomial.hpp"

using namespace Modulus;

int main()
{
    Polynomial<int> p;
    p + p;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我对[!]in 下的行进行注释时,我得到的错误是friends can only be classes or functions(Clang ++)或declaration of ‘operator+’ as non-function(g ++).

对我来说,似乎编译器误认为两个运营商.一旦我学会了运算符重载的东西,一元和二元运算符是完全独立的,可以通过它们的参数个数唯一区分.

那么为什么会出现错误呢?使用标准实践使一元运算符成为朋友,使代码在两个编译器上编译良好.

Mik*_*our 4

当您在某个范围内声明某些内容时,它会隐藏任何更广泛范围内的同名声明。在这里,成员的声明operator+隐藏了非成员的声明。因此friend声明引用的是成员,而不是非成员,因此会出现错误。

如果您想在同一范围内引用两者,则需要限定名称:

Polynomial      operator +      () const { return *this; }

friend Polynomial Modulus::operator + <> (Polynomial const & p, Polynomial const & q);
                  ^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

  • libstdc++ 使用“.tcc”。一些编辑器甚至将其识别为 C++ 源文件扩展名(用于语法突出显示、缩进等),因此如果您想以这种方式执行操作,那么遵循这种方法并不是一个坏方法。 (3认同)