几个星期前,我问question关于"变种的问题"矩阵课,现在我试图在不同的项目中应用答案,我收到错误,我不明白。基本上问题是我不明白如何使用" variadic" matrix class作为另一个类中的属性(在最小工作示例中名为Test)。
最小的工作示例 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};
}
使用&#34; g ++ -std = c ++ 14 * .cpp -o cfd.out&#34;进行编译后,出现以下类型的错误:
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;
}
所以我想了解课程中出了什么问题以及我能做些什么来解决它。
答案 0 :(得分:1)
正如@Oliv和@AndyG所说,你需要为依赖项添加#include
:
#include <vector>
#include <memory>
您应该在定义Matrix
之前包含它们。一种方法是在#include
中移动Test.hpp
语句,但更好的方法是将它们添加到Matrix.hpp
的开头,以便矩阵头文件是自包含的。