C++ 无法重载嵌套数组的运算符<;数组<;浮动,n>;,m>;

C++ 无法重载嵌套数组的运算符<;数组<;浮动,n>;,m>;,c++,boost,C++,Boost,我创建了一个简单的矩阵定义,如下所示: template <size_t m, size_t n> using Matrix = boost::array<boost::array<float, n>, m>; 我无法理解部分模板专门化,并且通常不理解为什么不能重载操作符 clang++10.0.1编译输出为 matri.cpp:10:21: error: nested name specifier 'Matrix<m, n>::' for de

我创建了一个简单的矩阵定义,如下所示:

template <size_t m, size_t n>
using Matrix = boost::array<boost::array<float, n>, m>;
我无法理解部分模板专门化,并且通常不理解为什么不能重载操作符

clang++10.0.1编译输出为

matri.cpp:10:21: error: nested name specifier 'Matrix<m, n>::' for declaration does not refer into a class, class template
 or class template partial specialization
float& Matrix<m,n>::operator[](uint32_t i, uint32_t j) {
       ~~~~~~~~~~~~~^
matri.cpp:11:14: error: invalid use of 'this' outside of a non-static member function
    return &(this[i][j]);
             ^
matri.cpp:11:19: error: use of undeclared identifier 'i'
    return &(this[i][j]);
                  ^
matri.cpp:11:22: error: use of undeclared identifier 'j'
    return &(this[i][j]);
matri.cpp:10:21:错误:嵌套名称说明符“Matrix::”for声明未引用类、类模板
或类模板部分专门化
浮点和矩阵::运算符[](uint32\u t i,uint32\u t j){
~~~~~~~~~~~~~^
matri.cpp:11:14:错误:在非静态成员函数之外使用“this”无效
返回和(本[i][j]);
^
matri.cpp:11:19:错误:使用未声明的标识符“i”
返回和(本[i][j]);
^
matri.cpp:11:22:错误:使用未声明的标识符“j”
返回和(本[i][j]);

这种方法存在多个问题

  • 由于
    Matrix
    只是一个别名,因此您试图对
    boost::array
    的成员函数(
    operator[]
    )进行部分专门化,但您只能部分专门化整个类模板,而不仅仅是成员函数

  • 运算符[]
    是二进制的(只有一个操作数必须在括号内),在用户定义类中重载时不能更改。如果不喜欢链接这些运算符,可以重载
    运算符()

下面显示了一个用户定义的<代码>矩阵类的最小实现。如果你需要更多的东西,考虑使用一个已经存在的线性代数库。

#include <array>
#include <initializer_list>
#include <iostream>
#include <numeric>

template <class Type, size_t Rows, size_t Cols>
class Matrix
{
    std::array<Type, Rows * Cols> m_;
public:
    Matrix() = default;
    Matrix(std::initializer_list<std::initializer_list<Type>> src) {
        auto dest{ m_.begin() };
        for ( auto const& row : src ) {
            std::copy(row.begin(), row.end(), dest);
            dest += Cols;
        }
    }
    static constexpr size_t rows() {
        return Rows;
    }
    static constexpr size_t columns() {
        return Cols;
    }
    auto begin() {
        return m_.begin();
    }
    auto begin() const {
        return m_.begin();
    }
    auto end() {
        return m_.end();
    }
    auto end() const {
        return m_.end();
    }
    Type operator() (size_t i, size_t j) const { 
        return m_[i * Cols + j];
    }
    Type& operator() (size_t i, size_t j) { std::cout << '*';
        return m_[i * Cols + j];
    }
};

template< class T, size_t R, size_t C >
std::ostream& operator<< (std::ostream& os, Matrix<T, R, C> const& m) {
    for ( size_t i{}; i < R; ++i ) {
        for ( size_t j{}; j < C; ++j ) {
            os << ' ' << m(i, j);
        }
        os << '\n';
    }
    return os;
}

int main() {
    Matrix<float, 3, 4> a{};
    std::iota(a.begin(), a.end(), 1);
    std::cout << a << '\n';

    Matrix<double, 3, 4> b {
        {1, 4, 7, 10},
        {2, 5, 8, 11},
        {3, 6, 9, 12}
    };
    std::cout << b << '\n';
}
#包括
#包括
#包括
#包括
模板
类矩阵
{
std::数组m_;
公众:
矩阵()=默认值;
矩阵(标准::初始值设定项\u列表src){
自动目的地{m_.begin()};
用于(自动常量和行:src){
std::copy(row.begin()、row.end()、dest);
dest+=Cols;
}
}
静态constexpr size\u t行(){
返回行;
}
静态constexpr size\u t columns(){
返回Cols;
}
自动开始(){
返回m_.begin();
}
自动开始()常量{
返回m_.begin();
}
自动结束(){
返回m_.end();
}
自动结束()常量{
返回m_.end();
}
类型运算符()
返回m_[i*Cols+j];
}
类型和运算符()(大小i,大小j){std::cout

std::ostream&operatorAlas,
operator[]
只接受一个参数。您可以将参数设置为
…但这可能会破坏代码更清晰的目的。为了实现这一点,类
boost::array
必须声明此运算符重载。在
boost::array
类中没有定义此类重载,并且您无法以任意方式定义它C样式,这样C++不工作。更不用说 [C]< /Cult>重载总是一个参数。@ SAMVARSHIVCHIKK真的,但是将来可能会改变(至少有一个建议:):被埋入:运算符[]/Cult>可以重载的是二进制缀缀,如<代码> A[x]
--括号前有一个操作数,括号内有一个,而不是两个。这是否回答了您的问题?
#include <array>
#include <initializer_list>
#include <iostream>
#include <numeric>

template <class Type, size_t Rows, size_t Cols>
class Matrix
{
    std::array<Type, Rows * Cols> m_;
public:
    Matrix() = default;
    Matrix(std::initializer_list<std::initializer_list<Type>> src) {
        auto dest{ m_.begin() };
        for ( auto const& row : src ) {
            std::copy(row.begin(), row.end(), dest);
            dest += Cols;
        }
    }
    static constexpr size_t rows() {
        return Rows;
    }
    static constexpr size_t columns() {
        return Cols;
    }
    auto begin() {
        return m_.begin();
    }
    auto begin() const {
        return m_.begin();
    }
    auto end() {
        return m_.end();
    }
    auto end() const {
        return m_.end();
    }
    Type operator() (size_t i, size_t j) const { 
        return m_[i * Cols + j];
    }
    Type& operator() (size_t i, size_t j) { std::cout << '*';
        return m_[i * Cols + j];
    }
};

template< class T, size_t R, size_t C >
std::ostream& operator<< (std::ostream& os, Matrix<T, R, C> const& m) {
    for ( size_t i{}; i < R; ++i ) {
        for ( size_t j{}; j < C; ++j ) {
            os << ' ' << m(i, j);
        }
        os << '\n';
    }
    return os;
}

int main() {
    Matrix<float, 3, 4> a{};
    std::iota(a.begin(), a.end(), 1);
    std::cout << a << '\n';

    Matrix<double, 3, 4> b {
        {1, 4, 7, 10},
        {2, 5, 8, 11},
        {3, 6, 9, 12}
    };
    std::cout << b << '\n';
}