矩阵类,可变参数构造函数

时间:2017-10-25 16:51:46

标签: c++ matrix

我正在尝试创建一个简单的矩阵类,重点是我使用标准指针来存储数据..而且我不知道2件事情 我怎样才能解决这个构造函数的问题:

In file included from matrixDrive.cpp:3:0:
matrix.H: In constructor ‘constexpr Matrix<U>::Matrix(std::size_t, std::size_t, Ts&& ...)’:
matrix.H:93:1: error: expected identifier before ‘{’ token
 {
 ^
matrix.H: In instantiation of ‘constexpr Matrix<U>::Matrix(std::size_t, std::size_t, Ts&& ...) [with Ts = {double, double, double, double, double, double}; data_type = double; std::size_t = long unsigned int]’:
matrixDrive.cpp:11:68:   required from here
matrix.H:96:19: error: cannot convert ‘<brace-enclosed initializer list>’ to ‘double’ in assignment
         data[i++] = {std::forward<Ts>(args)...};
         ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
matrixDrive.cpp: In function ‘int main()’:
matrixDrive.cpp:13:3: error: expected ‘,’ or ‘;’ before ‘return’
   return 0;
   ^~~~~~

我收到了错误:

# include <iostream>
# include <utility>
# include <iomanip>
# include <vector>
# include <exception>
# include <iterator>
# include <cassert>

template <class U> class Matrix ;

template <class U>
std::ostream& operator<<(std::ostream& , Matrix<U>& );

template <class U>
std::ostream& operator<<(std::ostream& ,const Matrix<U>& ); 


//- class declararation
//
template <typename data_type = double>
class Matrix {

   public:   
    //- friend function
    template <class U>
    friend std::ostream& operator<<(std::ostream& ,Matrix<U>& ); 

    template <class U>
    friend std::ostream& operator<<(std::ostream& ,const Matrix<U>& ); 





   public:
    constexpr Matrix(std::size_t r = 3 , std::size_t c = 3) noexcept;  

    constexpr Matrix(std::size_t r, std::size_t c, data_type val) noexcept;  

    template <typename ... Ts>   
    constexpr Matrix(std::size_t row , std::size_t col, Ts&&... args) noexcept;  

    virtual ~Matrix() noexcept ; 


    auto constexpr zeros() noexcept ;

    auto constexpr initialize(data_type) noexcept ;

    data_type& operator()(std::size_t, std::size_t);  

//-------
   private:   

      data_type *data     ;
      std::size_t row     ;
      std::size_t columns ;

      auto constexpr isAllocate() noexcept { return data != nullptr ; } 

};

// Matrix definition

//- standard constructor
template<typename data_type>
constexpr Matrix<data_type>::Matrix(std::size_t r, std::size_t c) noexcept : row{r}, columns{c}, 
                                                                     data{new data_type[r*c]}
{
      this->zeros();
}


template<typename data_type>
constexpr Matrix<data_type>::Matrix(std::size_t r, std::size_t c, data_type val) noexcept : row{r}, columns{c}, 
                                                                                            data{new data_type[r*c]}
{
      this->initialize(val);
}  


//--- construct by list of arguments
template<typename data_type>
template <typename ... Ts>   
constexpr Matrix<data_type>::Matrix(std::size_t row , 
                                    std::size_t col ,
                                    Ts&&... args     ) noexcept : row{row}, columns{col},
                                                                   data{ new data_type[row*col] },

{
        std::size_t i =0;    
        assert(sizeof...(args) == row*columns );    
        data[i++] = (std::forward<Ts>(args)...);          
}


// destructor
template<typename data_type>
Matrix<data_type>::~Matrix() noexcept 
{
      if( isAllocate() )
            delete[] data; 
}





//----------------------------------------------------------------------------------------------------
//

template <typename data_type>
auto constexpr Matrix<data_type>::zeros() noexcept {
   if(isAllocate())
     for(size_t i=0; i< row*columns ; i++)
            data[i] = 0; 
}


template <typename data_type>
auto constexpr Matrix<data_type>::initialize(data_type val) noexcept
{
      if(isAllocate())
         for(size_t i=0 ; i < row*columns; i++)
            data[i] = val ;
}




//-----------

template <typename data_type>
data_type& Matrix<data_type>::operator()(std::size_t i, std::size_t j) { return data[(i-1) + row* (j-1)] ; }  


// non member function 

template <class U>
std::ostream& operator<<(std::ostream& out ,Matrix<U>& mat)
{
    for(std::size_t r = 1; r < mat.row+1 ; r++)
    {
      for(std::size_t c = 1; c < mat.columns+1 ; c++)
      {
          out << mat(r,c) << ' ' ;  
      }
      out << "\n" ;
    }
}

template <class U>
std::ostream& operator<<(std::ostream& out , const Matrix<U>& mat) 
{
    for(std::size_t r = 1; r < mat.row+1 ; r++)
    {
      for(std::size_t c = 1; c < mat.columns+1 ; c++)
      {
          out << mat(r,c) << ' ';  
      }
      out << "\n" ;
    }
}

这里是整个实施:

# include <iostream>
# include <iomanip>
# include "matrix.H"

using namespace std;

int main() {

  Matrix<double> m1, m2(6,3);    

  Matrix<double> m3(3,2,1.12,2.434,3.546546,4.657,5.675675,6.542354)    

  return 0;    
}

和主要功能:

<RibbonApplicationMenu.SmallImageSource>
  <DrawingImage>
    <DrawingImage.Drawing>
      <GeometryDrawing>
        <GeometryDrawing.Geometry>
          <RectangleGeometry Rect="0,0,20,20"></RectangleGeometry>
        </GeometryDrawing.Geometry>
        <GeometryDrawing.Brush>
          <VisualBrush Stretch="Uniform">
            <VisualBrush.Visual>
                <TextBlock Text="File" FontSize="16" Foreground="White" />
            </VisualBrush.Visual>
          </VisualBrush>
        </GeometryDrawing.Brush>
      </GeometryDrawing>
    </DrawingImage.Drawing>
  </DrawingImage>
</RibbonApplicationMenu.SmallImageSource>

提前感谢您的宝贵帮助!

1 个答案:

答案 0 :(得分:0)

您尝试parameter pack expansion的方式不起作用。它将扩展整个参数列表,并尝试将它们分配给data[1]

Create std::array from variadic template的答案也适用于此:

template<typename data_type>
template <typename ... Ts>
constexpr Matrix<data_type>::Matrix(std::size_t row ,
                                    std::size_t col ,
                                    Ts&&... args     ) noexcept : row{row}, columns{col},
                                                                   data{ new data_type[row*col] }

{
        std::size_t i =0;
        assert(sizeof...(args) == row*columns );

        std::initializer_list<data_type> il ( { std::forward<Ts>(args)... } );
        std::copy(il.begin(), il.end(), data);
}

请注意,您发布的代码有很多错误。它甚至没有编译,因为main函数中缺少一个分号。如果使用-Wall -Wextra -pendantic进行编译,还会收到很多警告。