【问题标题】:No match for operator+ , and no match for vector construction call in c++不匹配 operator+ ,也不匹配 c++ 中的向量构造调用
【发布时间】:2019-04-01 15:09:09
【问题描述】:

我正在尝试使用表达式模板来实现矩阵加法。我面临一些麻烦。这是我的矩阵代码:

#include<iostream>
#include<vector>
#include<cassert>

template <typename T>
class MatrixExpression {
  public:
    double operator[](size_t i) const { return static_cast<T const&>(*this)[i];}
    size_t size()const { return static_cast<T const&>(*this).size(); }
};
template<typename T>
class Matrix:public MatrixExpression<Matrix<T>>
{
    std::vector<std::vector<T>> mat;

    public:
    Matrix(std::size_t m, std::size_t n):mat(m,std::vector<T>(n)){}



    class Proxy
    {
        std::vector<T> vec;
        public:
        Proxy(std::vector<T> vec):vec(vec){ }

        T operator[](std::size_t i){ return vec[i];}
        //T &operator[](std::size_t i){ return vec[i];}
        std::size_t size() const{ return vec.size(); }
    };

    Proxy operator[](std::size_t i) const { return Proxy(mat[i]); }
    //Proxy &operator[](std::size_t i)      { return Proxy(mat[i]); }
    size_t size() const { return mat.size(); }

    Matrix(std::initializer_list<std::initializer_list<T>> lst)
    {
        int m=0,n=0;
        for(auto l:lst )
        {
            for(auto v:l)
            {
                n++;
            }
            m++;
        }
        int i=0,j=0;
        mat(m,std::vector<T>(n));
        for(auto l:lst )
        {
            for(auto v:l)
            {
                mat[i].push_back(v);
            }
            i++;
        }
    }


    Matrix(MatrixExpression<T> const& matx):mat(matx.size(),std::vector<T>(matx[0].size))
    {
        for(int i=0;i<matx.size();i++)
        {
            for(int j=0;j<matx[0].size();j++)
            {
                mat[i][j] = matx[i][j];
            }
        }
    }
};

template<typename T, typename X, typename Y>
class MatrixSum:public MatrixExpression<MatrixSum<T,X,Y>>
{
    X const& x;
    Y const& y;

    public:
    MatrixSum(X const& x1, Y const& y1):x(x1),y(y1){
        assert(x1.size()==y1.size());
        assert(x1[0].size()==y1[0].size());
    }

    class ProxySum
    {
        std::vector<T> vec1,vec2;
        public:
        ProxySum(std::vector<T> vec1,std::vector<T> vec2):vec1(vec1),vec2(vec2){ }

        T operator[](std::size_t i){ return vec1[i] + vec2[i];}
        //T &operator[](std::size_t i){ return vec1[i] + vec2[i];}
        std::size_t size() const{ return vec1[0].size(); }
    };
    ProxySum operator[](std::size_t i) const { return ProxySum(x[i],y[i]); }
    //ProxySum &operator[](std::size_t i){ return ProxySum(x[i],y[i]); }
    size_t size() const { return x.size(); } 

};

template<typename T,typename X,typename Y>
MatrixSum<T,X,Y>
operator+(X const& x, Y const& y)
{
    return MatrixSum<T,X,Y>(x,y);
}

我在使用 Matrix 类时遇到两个错误。首先是矩阵不存在运算符+(我在测试中使用了int),即使我已经为'+'实现了运算符重载,另一个错误是在矩阵的第二个构造函数中。它说我对 mat 变量的构造函数的调用是无效的。但是向量确实有这样的构造函数

【问题讨论】:

    标签: c++11 templates operator-overloading overloading expression-templates


    【解决方案1】:

    1) 以下行不是有效的 C++ 语法:

    mat(m,std::vector<T>(n));
    

    你应该在构造函数的初始化列表中初始化mat成员对象,像这样(假设最外面的initializer_list不为空):

    Matrix(std::initializer_list<std::initializer_list<T>> lst) : mat(lst.size(), std::vector<T>(begin(lst)->size()))
    

    2) 至于你提供的operator +

    template<typename T,typename X,typename Y>
    MatrixSum<T,X,Y>
    operator+(X const& x, Y const& y)
    {
        return MatrixSum<T,X,Y>(x,y);
    }
    

    注意,T 模板参数是不可推导的,所以编译器无法判断,因此无法使用该运算符。调用它的唯一方法是这样的:

    matrix1.operator +<some_type>(matrix2);
    

    ...这可能不是你想要的。

    正确的方法是在编译时尝试计算 T,基于 XY 类型,使用一些元编程。

    【讨论】:

    • 你能给我一些想法吗?我是 C++ 模板的新手。我对此没有深入的了解。
    • @Shantanu Shinde 如果 T 是 sum 类型,则可以在矩阵中定义 value_type,然后推导出 sum 类型如下: decltype(std::decval () + std::decval())
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    • 2021-05-21
    • 2020-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多