0

我对模板类的绑定模板友元函数有一些问题。我参考了与我有类似和简单问题的页面:vect.hpp:13:33: error: declaration of 'operator<<' as non-function ,但我仍然感到困惑,问题无法解决。这是我的代码:

#include<iostream>  
#include<valarray>

using namespace std;

//forward declaration
template<typename ElemType, size_t row, size_t col = row>
class matrix;

template<typename ET, size_t R, size_t C>
matrix<ET, R, C> operator*(ET multier, matrix<ET, R, C> mattem);

template<typename ElemType, size_t row, size_t col>
class matrix
{
    private:
        valarray<ElemType> mat;
    public:
        matrix(): mat(row*col) {}
        matrix(initializer_list<ElemType>);

        matrix operator*(ElemType multier) const
        {
            matrix mattem;
            mattem.mat = this->mat*multier;
            return mattem;
        }
        
        //friend function prototype
        friend matrix<ElemType, row, col> operator*<>(ElemType multier, matrix<ElemType, row, col> mattem);

        void show() const
        {
            for (ElemType Elem : this->mat)
                cout << Elem << " ";
            cout << endl;
        }
};

template<typename ElemType, size_t row, size_t col>
matrix<ElemType, row, col>::matrix(initializer_list<ElemType> ini)
{
    try
    {
        if (ini.size() != row*col)
            throw "Inappropriate length!";
        this->mat = ini;
    }
    catch (const char * str)
    {
        cout << str << endl;
    }
}

//friend function definition
template<typename ElemType, size_t row, size_t col>
matrix<ElemType, row, col> operator*<>(ElemType multier, matrix<ElemType, row, col> mattem)
{
    return mattem*multier;
}

int main(void)
{
    matrix<int, 2, 3> test = {1, 3, 5, 8, 9, 7};
    matrix<int, 2, 3> abc =2*test;
    abc.show();
}

WSL2 (Ubuntu 9.3.0-17ubuntu1~20.04)我在using中编译并运行它gcc version 9.3.0,我得到了一系列错误,如下所示:

test.cpp:28:51: error: declaration of ‘operator*’ as non-function
   28 |         friend matrix<ElemType, row, col> operator*<>(ElemType multier, matrix<ElemType, row, col> mattem);
      |                                                   ^
test.cpp:28:51: error: expected ‘;’ at end of member declaration
   28 |         friend matrix<ElemType, row, col> operator*<>(ElemType multier, matrix<ElemType, row, col> mattem);
      |                                                   ^
      |                                                    ;
test.cpp:28:52: error: expected unqualified-id before ‘&lt;’ token
   28 |         friend matrix<ElemType, row, col> operator*<>(ElemType multier, matrix<ElemType, row, col> mattem);
      |                                                    ^
test.cpp:54:91: error: template-id ‘operator*<>’ in declaration of primary template
   54 | matrix<ElemType, row, col> operator*<>(ElemType multier, matrix<ElemType, row, col> mattem)
      |                                                                                           ^
test.cpp: In function ‘int main()’:
test.cpp:62:29: error: conversion from ‘matrix<[...],[...],2>’ to non-scalar type ‘matrix<[...],[...],3>’ requested
   62 |     matrix<int, 2, 3> abc =2*test;
      |                            ~^~~~~
4

2 回答 2

0

我发现在模板类中处理友元运算符最可靠的方法是将完整的定义放在类本身中:

//forward declaration
template<typename ElemType, size_t row, size_t col = row>
class matrix;
/*
template<typename ET, size_t R, size_t C>
matrix<ET, R, C> operator*(ET multier, matrix<ET, R, C> mattem);
*/
template<typename ElemType, size_t row, size_t col>
class matrix
...
        //friend function prototype
        friend matrix<ElemType, row, col> operator *  (ElemType multier, matrix<ElemType, row, col> mattem){
            return mattem * multier;
        }
...
/*
//friend function definition
template<typename ElemType, size_t row, size_t col>
matrix<ElemType, row, col> operator*(ElemType multier, matrix<ElemType, row, col> mattem)
{
    return mattem*multier;
}
*/
于 2020-12-17T10:40:04.403 回答
0

你不需要<>在那个声明中。令人讨厌的是,第一个错误并没有告诉您,而是由于编译器不知道您的意思而导致的其他错误。

您可以将声明简化为

friend matrix operator*(ElemType multier, matrix mattem);

定义仍然需要完整的模板参数列表

template<typename ElemType, size_t row, size_t col>
matrix<ElemType, row, col> operator*(ElemType multier, matrix<ElemType, row, col> mattem)
{
    return mattem*multier;
}
于 2020-12-17T09:56:00.863 回答