Vor ein paar Wochen fragte ich diese question über eine "variadic" Matrix-Klasse und jetzt versuche ich, die Antwort in einem anderen Projekt anzuwenden, und ich bekomme Fehler, die ich nicht verstehe. Im Grunde ist das Problem, dass ich nicht verstehe, wie man die "variadic" -Matrixklasse als Attribut in einer anderen Klasse verwendet (die im minimalen Arbeitsbeispiel Test genannt wird).Verwenden variadic Vorlage als Attribut
Minimal Arbeits Beispiel 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};
}
Nach dem Kompilieren mit "g ++ -std = C++ 14 * CPP -o cfd.out", ich die folgende Art von Fehlermeldungen erhalten:
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) {
So weit ich es verstehe, gibt es ein Problem beim Erkennen des Vorlagentyps, aber ich weiß nicht, wie ich es lösen soll. Schließlich möchte ich bemerken, dass ich keine Probleme mit der Verwendung der Matrix-Klasse außerhalb einer anderen Klasse hatte. Zum Beispiel scheint das folgende Stück Code gut zu funktionieren.
#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;
}
Also ich würde gerne verstehen, was in einer Klasse schief geht und was ich kann, es zu lösen tun.
Haben Sie nicht vergessen, #include ?? –
Oliv
Fügen Sie auch '#include' zu Ihrer .hpp-Datei hinzu. Im Allgemeinen fehlt diese Datei includes. –
AndyG
@Oliv Ich habe tatsächlich vergessen #include und #include in diesem Testfall. Hinzugefügt sie, aber änderte das Problem nicht. Wird die Frage aktualisieren. –