2017-09-18 14 views
1

数週間前、私はこの「」に「variadic」マトリックスクラスについて尋ねましたが、今は別のプロジェクトで回答を適用しようとしています。基本的に問題は、「variadic」マトリックスクラスを別のクラスの属性として使用する方法を理解していないことです。属性としてバリアントテンプレートを使用

最小実施例 main.cppに:

#include <iostream> 
#include <memory> 
#include "matrix.hpp" 
#include "test.hpp" 
using namespace std; 

int main(int argc, char *argv[]) 
{ 
    Test T(); 
    return 0; 
} 

matrix.hpp:

#ifndef MATRIX_H 
#define MATRIX_H 

template<typename T> 
class Matrix 
    { 
     private: 
     std::vector<size_t> dimensions; 
     std::unique_ptr<T[]> _data; 

     public: 
     Matrix() 
     {} 

     Matrix(std::vector<size_t> dims) 
     : dimensions(std::move(dims)) 
     { 
      size_t size = flat_size(); 
      _data = std::make_unique<T[]>(size); 
     } 

     template<typename ... Dimensions> 
     Matrix(size_t dim, Dimensions&&... dims) 
     { 
      size_t size = apply_dimensions(dim, std::forward<Dimensions>(dims)...); 
      _data = std::make_unique<T[]>(size); 
     } 

     template<typename ... Indexes> 
     T & operator()(size_t idx, Indexes&& ... indexes) 
     { 
      if (sizeof...(indexes)+1 != dimensions.size()) 
       throw std::runtime_error("Incorrect number of parameters used to retrieve Matrix Data!"); 
      size_t flat_index = get_flat_index(0, idx, std::forward<Indexes>(indexes)...); 
      return at(flat_index); 
     } 

     template<typename ... Indexes> 
     T const& operator()(size_t idx, Indexes&& ... indexes) const 
     { 
      if (sizeof...(indexes)+1 != dimensions.size()) 
       throw std::runtime_error("Incorrect number of parameters used to retrieve Matrix Data!"); 
      size_t flat_index = get_flat_index(0, idx, std::forward<Indexes>(indexes)...); 
      return at(flat_index); 
     } 

     Matrix(const Matrix&) 
     {} 

     Matrix(Matrix&& other) 
     : Matrix() 
     { 
      swap(*this, other); 
     } 

     Matrix & operator=(Matrix other) 
     { 
      swap(*this, other); 
      return *this; 
     } 

     friend void swap(Matrix& first, Matrix& second) 
     { 
      using std::swap; 
      swap(first.dimensions, second.dimensions); 
      swap(first._data, second._data); 
     } 


     size_t dimension_size(size_t dim) const { 
      return dimensions[dim]; 
     } 

     size_t num_of_dimensions() const { 
      return dimensions.size(); 
     } 

    private: 
    template<typename ... Dimensions> 
    size_t apply_dimensions(size_t dim, Dimensions&& ... dims) 
    { 
     dimensions.emplace_back(dim); 
     return dim * apply_dimensions(std::forward<Dimensions>(dims)...); 
    } 

    size_t apply_dimensions(size_t dim) 
    { 
     dimensions.emplace_back(dim); 
     return dim; 
    } 

    template<typename ... Indexes> 
    size_t get_flat_index(size_t dim, size_t index, Indexes&& ... indexes) const 
    { 
     return get_offset(index, dim) + get_flat_index(dim + 1, std::forward<Indexes>(indexes)...); 
    } 

    size_t get_flat_index(size_t dim, size_t index) const 
    { 
     return get_offset(index, dim); 
    } 

    size_t get_offset(size_t index, size_t dim) const 
    { 
     if (index >= dimensions[dim]) 
      throw std::runtime_error("Index out of Bounds"); 
     for (size_t i = dim + 1; i < dimensions.size(); i++) 
     { 
      index *= dimensions[i]; 
     } 
     return index; 
    } 

    T& at(size_t flat_index) { 
     return _data[flat_index]; 
    } 

    T const& at(size_t flat_index) const { 
     return _data[flat_index]; 
    } 

    size_t flat_size() const { 
     size_t size = 1; 
     for (size_t dim : dimensions) 
      size *= dim; 
     return size; 
    } 
}; 

#endif // MATRIX_H 

test.hpp:

#ifndef TEST_H 
#define TEST_H 
#include "matrix.hpp" 
#include <vector> 
#include <memory> 
class Test 
{ 
public: 
    Test(); 
    Matrix<double>* temp = NULL; 
    Matrix<double> mat; 
}; 
#endif // TEST_H 

TEST.CPP:

#include "test.hpp" 

Test::Test() 
{ 
    mat = Matrix<double>{9, 2, 8}; 
} 

は "G ++ -std = C++ 14 * .cppファイル-o cfd.out" でコンパイルした後、私はエラーを次のような取得:これまでのところ、私は理解し

matrix.hpp:8:14: error: ‘vector’ in namespace ‘std’ does not name a template type 
    std::vector<size_t> dimensions; 
     ^
matrix.hpp:15:27: error: expected ‘)’ before ‘<’ token 
    Matrix(std::vector<size_t> dims) 
        ^
matrix.hpp: In member function ‘T& Matrix<T>::operator()(size_t, Indexes&& ...)’: 
matrix.hpp:32:41: error: ‘dimensions’ was not declared in this scope 
     if (sizeof...(indexes)+1 != dimensions.size()) 
            ^
matrix.hpp: In member function ‘const T& Matrix<T>::operator()(size_t, Indexes&& ...) const’: 
matrix.hpp:41:41: error: ‘dimensions’ was not declared in this scope 
     if (sizeof...(indexes)+1 != dimensions.size()) 
            ^
matrix.hpp: In member function ‘size_t Matrix<T>::dimension_size(size_t) const’: 
matrix.hpp:71:20: error: ‘dimensions’ was not declared in this scope 
     return dimensions[dim]; 
matrix.hpp: In member function ‘size_t Matrix<T>::num_of_dimensions() const’: 
matrix.hpp:75:20: error: ‘dimensions’ was not declared in this scope 
     return dimensions.size(); 
       ^
matrix.hpp: In member function ‘size_t Matrix<T>::apply_dimensions(size_t, Dimensions&& ...)’: 
matrix.hpp:82:13: error: ‘dimensions’ was not declared in this scope 
     dimensions.emplace_back(dim); 
     ^
matrix.hpp: In member function ‘size_t Matrix<T>::apply_dimensions(size_t)’: 
matrix.hpp:88:13: error: ‘dimensions’ was not declared in this scope 
     dimensions.emplace_back(dim); 
     ^
matrix.hpp: In member function ‘size_t Matrix<T>::get_offset(size_t, size_t) const’: 
matrix.hpp:105:26: error: ‘dimensions’ was not declared in this scope 
     if (index >= dimensions[dim]) 
        ^
matrix.hpp:107:42: error: ‘dimensions’ was not declared in this scope 
     for (size_t i = dim + 1; i < dimensions.size(); i++) 
            ^
matrix.hpp: In member function ‘size_t Matrix<T>::flat_size() const’: 
matrix.hpp:124:31: error: ‘dimensions’ was not declared in this scope 
     for (size_t dim : dimensions) 
         ^
In file included from test.hpp:3:0, 
      from test.cpp:1: 
matrix.hpp:8:14: error: ‘vector’ in namespace ‘std’ does not name a template type 
    std::vector<size_t> dimensions; 
     ^
matrix.hpp:9:14: error: ‘unique_ptr’ in namespace ‘std’ does not name a template type 
    std::unique_ptr<T[]> _data; 
     ^
matrix.hpp:15:27: error: expected ‘)’ before ‘<’ token 
    Matrix(std::vector<size_t> dims) 
        ^
matrix.hpp:23:23: error: expected ‘)’ before ‘dim’ 
    Matrix(size_t dim, Dimensions&&... dims) 
       ^
matrix.hpp:30:24: error: ‘size_t’ was not declared in this scope 
    T & operator()(size_t idx, Indexes&& ... indexes) 
        ^
matrix.hpp:30:43: error: expected primary-expression before ‘&&’ token 
    T & operator()(size_t idx, Indexes&& ... indexes) 
            ^
matrix.hpp:30:46: error: expected primary-expression before ‘...’ token 
    T & operator()(size_t idx, Indexes&& ... indexes) 
             ^
matrix.hpp:30:57: error: declaration of ‘operator()’ as non-function 
    T & operator()(size_t idx, Indexes&& ... indexes) 
                ^
matrix.hpp:39:29: error: ‘size_t’ was not declared in this scope 
    T const& operator()(size_t idx, Indexes&& ... indexes) const 
         ^
matrix.hpp:39:48: error: expected primary-expression before ‘&&’ token 
    T const& operator()(size_t idx, Indexes&& ... indexes) const 
              ^
matrix.hpp:39:51: error: expected primary-expression before ‘...’ token 
    T const& operator()(size_t idx, Indexes&& ... indexes) const 
              ^
matrix.hpp:39:62: error: declaration of ‘operator()’ as non-function 
    T const& operator()(size_t idx, Indexes&& ... indexes) const 
                 ^
matrix.hpp:70:9: error: ‘size_t’ does not name a type 
    size_t dimension_size(size_t dim) const { 
    ^
matrix.hpp:74:9: error: ‘size_t’ does not name a type 
    size_t num_of_dimensions() const { 
    ^
matrix.hpp:80:9: error: ‘size_t’ does not name a type 
    size_t apply_dimensions(size_t dim, Dimensions&& ... dims) 
    ^
matrix.hpp:86:9: error: ‘size_t’ does not name a type 
    size_t apply_dimensions(size_t dim) 
    ^
matrix.hpp:93:9: error: ‘size_t’ does not name a type 
    size_t get_flat_index(size_t dim, size_t index, Indexes&& ... indexes) 
    ^
matrix.hpp:98:9: error: ‘size_t’ does not name a type 
    size_t get_flat_index(size_t dim, size_t index) const 
    ^
matrix.hpp:103:9: error: ‘size_t’ does not name a type 
    size_t get_offset(size_t index, size_t dim) const 
    ^
matrix.hpp:114:12: error: expected ‘;’ at end of member declaration 
    T& at(size_t flat_index) { 
     ^
matrix.hpp:114:22: error: expected ‘)’ before ‘flat_index’ 
    T& at(size_t flat_index) { 
       ^
matrix.hpp:118:18: error: expected ‘;’ at end of member declaration 
    T const& at(size_t flat_index) const { 
      ^
matrix.hpp:118:21: error: redeclaration of ‘const T& Matrix<T>::at’ 
    T const& at(size_t flat_index) const { 
       ^
matrix.hpp:114:15: note: previous declaration ‘T& Matrix<T>::at’ 
    T& at(size_t flat_index) { 
     ^
matrix.hpp:118:28: error: expected ‘)’ before ‘flat_index’ 
    T const& at(size_t flat_index) const { 
         ^
matrix.hpp:122:9: error: ‘size_t’ does not name a type 
    size_t flat_size() const { 
    ^
matrix.hpp: In function ‘void swap(Matrix<T>&, Matrix<T>&)’: 
matrix.hpp:64:24: error: ‘std::swap’ has not been declared 
     using std::swap; 
        ^
In file included from test.cpp:1:0: 
test.hpp: At global scope: 
test.hpp:8:28: error: ‘NULL’ was not declared in this scope 
Matrix<double>* temp = NULL; 
         ^
test.cpp: In constructor ‘Test::Test()’: 
test.cpp:5:33: error: no matching function for call to ‘Matrix<double>::Matrix(<brace-enclosed initializer list>)’ 
mat = Matrix<double>{9, 2, 8}; 
          ^
In file included from test.hpp:3:0, 
      from test.cpp:1: 
matrix.hpp:50:9: note: candidate: Matrix<T>::Matrix(Matrix<T>&&) [with T = double] 
    Matrix(Matrix&& other) 
    ^
matrix.hpp:50:9: note: candidate expects 1 argument, 3 provided 
matrix.hpp:47:9: note: candidate: Matrix<T>::Matrix(const Matrix<T>&) [with T = double] 
    Matrix(const Matrix&) 
    ^
matrix.hpp:47:9: note: candidate expects 1 argument, 3 provided 
matrix.hpp:12:9: note: candidate: Matrix<T>::Matrix() [with T = double] 
    Matrix() 
    ^
matrix.hpp:12:9: note: candidate expects 0 arguments, 3 provided 
matrix.hpp: In instantiation of ‘Matrix<T>::Matrix() [with T = double]’: 
test.cpp:3:12: required from here 
matrix.hpp:12:9: error: uninitialized reference member in ‘double&’ [-fpermissive] 
matrix.hpp:114:15: note: ‘double& Matrix<double>::at’ should be initialized 
    T& at(size_t flat_index) { 

を、そこにありますテンプレートタイプを認識する際の問題ですが、解決方法はわかりません。最後に、私は別のクラスの外で行列クラスを使用することに問題はなかったと言いたいと思います。たとえば、次のコードは正常に動作しているようです。

#include <iostream> 
#include <memory> 
#include "fcontainer.hpp" 
#include "printer.hpp" 
#include "matrix.hpp" 
#include "test.hpp" 
using namespace std; 

int main(int argc, char *argv[]) 
{ 
    std::cout << "Input the sizes of each of the dimensions.\n"; 
    std::string line; 
    std::getline(std::cin, line); 
    std::stringstream ss(line); 
    size_t dim; 
    std::vector<size_t> dimensions; 
    while(ss >> dim) 
     dimensions.emplace_back(dim); 
    Matrix<double> mat{6, 5}; 
    mat(5, 2) = 17; 
    Matrix<double>* temp = NULL; 
    mat = Matrix<double>{9, 2, 8}; 
    temp = &(mat); 
    mat(5, 1, 7) = 24; 
    cout << mat(5, 1, 7) << endl; 
    cout << (*temp)(5, 1, 7) << endl; 
    return 0; 
} 

だから私は、クラスと私はそれを解決するために行うことができますでうまくいかないかを理解したいと思います。 @Olivと@AndyGとして

+5

を#忘れていませんか? – Oliv

+0

また、.hppファイルに '#include 'を追加してください。一般に、ファイルが見つからない場合があります。 – AndyG

+0

@Olivこのテストケースでは、#と#include を実際に忘れました。それらを追加しましたが、問題は変わりませんでした。質問が更新されます。 –

答えて

1

はあなたが依存関係を#includeを追加する必要があり、言った:

#include <vector> 
#include <memory> 

Matrixが定義される前に、あなたがそれらを含める必要があります。その1つの方法は#includeステートメントを先にTest.hppに移動することですが、それをMatrix.hppの先頭に追加して、マトリックスヘッダーファイルが自己完結型になるようにしてください。

関連する問題