C++ 具有特定于枚举的实现和共享功能(CRTP)的类模板
我想设计一个C++ 具有特定于枚举的实现和共享功能(CRTP)的类模板,c++,C++,我想设计一个Matrix类,它允许指定内存管理的方法,即 Matrix<Allocator::vector, int> mv(2, 2); Matrix<Allocator::unique_pointer, int> mu(2, 2); mv(1, 1) = 1; mu(1, 2) = 1; 不幸的是,编译器抱怨 ./matrix.hpp:100:34: error: out-of-line definition of 'at' does not match any
Matrix
类,它允许指定内存管理的方法,即
Matrix<Allocator::vector, int> mv(2, 2);
Matrix<Allocator::unique_pointer, int> mu(2, 2);
mv(1, 1) = 1;
mu(1, 2) = 1;
不幸的是,编译器抱怨
./matrix.hpp:100:34: error: out-of-line definition of 'at' does not match any declaration in 'Matrix<linalg::Allocator::vector,
type-parameter-0-0>'
T& Matrix<Allocator::vector, T>::at(size_t i, size_t j) {
^
./matrix.hpp:103:20: error: use of undeclared identifier 'rows'
return data_[i * rows() + j];
/matrix.hpp:100:34:错误:“at”的行外定义与“matrix”中的任何声明都不匹配
T&Matrix::at(尺寸i,尺寸j){
^
./matrix.hpp:103:20:错误:使用未声明的标识符“行”
返回数据_ui*rows()+j];
我认为错误源于
template <typename T>
class Matrix<Allocator::vector, T> : public MatrixBase<T> {
private:
std::vector<T> data_;
};
模板
类矩阵:公共矩阵库{
私人:
std::矢量数据;
};
如何解决此问题?将定义移到内部将解决此问题。此问题是由于作用域
template <typename T>
class Matrix<Allocator::vector, T> : public MatrixBase<T> {
public: // or private:
T& at(size_t i, size_t j) {
return data_[i * MatrixBase<T>::rows() + j];
}
private:
std::vector<T> data_;
};
或者您可以在
C
中重新声明它,因此它将在C
的范围内。将定义移到内部将解决此问题。此问题是由于作用域
template <typename T>
class Matrix<Allocator::vector, T> : public MatrixBase<T> {
public: // or private:
T& at(size_t i, size_t j) {
return data_[i * MatrixBase<T>::rows() + j];
}
private:
std::vector<T> data_;
};
或者您可以在
C
中重新声明它,这样它将在C
的范围内。我已经修复了您的代码。给您:
using dim_t = std::pair<size_t, size_t>;
enum class Allocator { vector, raw_pointer, unique_pointer };
template <typename T>
class MatrixBase {
public:
MatrixBase() : MatrixBase(0, 0){};
MatrixBase(size_t m, size_t n) : dim_(m, n){};
size_t rows() const;
virtual T& at(size_t i, size_t j);
private:
dim_t dim_;
};
template <typename T>
size_t MatrixBase<T>::rows() const {
return dim_.first;
}
template <Allocator A, typename T>
class Matrix : public MatrixBase<T> {};
template <typename T>
class Matrix<Allocator::vector, T> : public MatrixBase<T> {
public:
T &at(size_t i, size_t j);
private:
std::vector<T> data_;
};
template <typename T>
T& Matrix<Allocator::vector, T>::at(size_t i, size_t j) {
return data_[i * this->rows() + j];
}
template <typename T>
class Matrix<Allocator::unique_pointer, T> : public MatrixBase<T> {
public:
T &at(size_t i, size_t j);
private:
std::unique_ptr<T[]> data_;
};
template <typename T>
T& Matrix<Allocator::unique_pointer, T>::at(size_t i, size_t j) {
return data_[i * this->rows() + j];
}
使用dim\u t=std::pair;
枚举类分配器{向量,原始指针,唯一指针};
模板
类矩阵基{
公众:
MatrixBase():MatrixBase(0,0){};
MatrixBase(size_t m,size_t n):dim_(m,n){};
行大小()常量;
虚拟T&at(尺寸i、尺寸j);
私人:
昏暗的;
};
模板
大小矩阵基::行()常量{
首先返回dim;
}
模板
类矩阵:公共矩阵基{};
模板
类矩阵:公共矩阵库{
公众:
T&at(尺寸i、尺寸j);
私人:
std::矢量数据;
};
模板
T&Matrix::at(尺寸i,尺寸j){
返回数据_ui*this->rows()+j];
}
模板
类矩阵:公共矩阵库{
公众:
T&at(尺寸i、尺寸j);
私人:
std::唯一的ptr数据;
};
模板
T&Matrix::at(尺寸i,尺寸j){
返回数据_ui*this->rows()+j];
}
首先,如果重写某个方法,则必须在派生类中声明它。其次,
rows()
函数在默认情况下无法作为成员解析。我已修复了您的代码。给您:
using dim_t = std::pair<size_t, size_t>;
enum class Allocator { vector, raw_pointer, unique_pointer };
template <typename T>
class MatrixBase {
public:
MatrixBase() : MatrixBase(0, 0){};
MatrixBase(size_t m, size_t n) : dim_(m, n){};
size_t rows() const;
virtual T& at(size_t i, size_t j);
private:
dim_t dim_;
};
template <typename T>
size_t MatrixBase<T>::rows() const {
return dim_.first;
}
template <Allocator A, typename T>
class Matrix : public MatrixBase<T> {};
template <typename T>
class Matrix<Allocator::vector, T> : public MatrixBase<T> {
public:
T &at(size_t i, size_t j);
private:
std::vector<T> data_;
};
template <typename T>
T& Matrix<Allocator::vector, T>::at(size_t i, size_t j) {
return data_[i * this->rows() + j];
}
template <typename T>
class Matrix<Allocator::unique_pointer, T> : public MatrixBase<T> {
public:
T &at(size_t i, size_t j);
private:
std::unique_ptr<T[]> data_;
};
template <typename T>
T& Matrix<Allocator::unique_pointer, T>::at(size_t i, size_t j) {
return data_[i * this->rows() + j];
}
使用dim\u t=std::pair;
枚举类分配器{向量,原始指针,唯一指针};
模板
类矩阵基{
公众:
MatrixBase():MatrixBase(0,0){};
MatrixBase(size_t m,size_t n):dim_(m,n){};
行大小()常量;
虚拟T&at(尺寸i、尺寸j);
私人:
昏暗的;
};
模板
大小矩阵基::行()常量{
首先返回dim;
}
模板
类矩阵:公共矩阵基{};
模板
类矩阵:公共矩阵库{
公众:
T&at(尺寸i、尺寸j);
私人:
std::矢量数据;
};
模板
T&Matrix::at(尺寸i,尺寸j){
返回数据_ui*this->rows()+j];
}
模板
类矩阵:公共矩阵库{
公众:
T&at(尺寸i、尺寸j);
私人:
std::唯一的ptr数据;
};
模板
T&Matrix::at(尺寸i,尺寸j){
返回数据_ui*this->rows()+j];
}
首先,如果重写方法,则必须在派生类中声明它函数在默认情况下无法作为成员解析。这是一个非法返回类型:
T&Matrix
@Viatorus Fixed请提供一个。@BartekBanachewicz Doneth这是一个非法返回类型:T&Matrix
@Viatorus Fixed请提供一个。@BartekBanachewicz Done为什么需要这个->
表示它只是nec如果存在歧义,但我没有看到任何命名conflict@bodokaiser看看这个:您不必在派生类中声明重写方法。这是错误的。我的回答表明了这一点。为什么需要this->
?说明只有在存在歧义的情况下才需要,但我看不到任何命名conflict@bodokaiser看看这个第一:您不必在派生类中声明重写方法。这是错误的。我的回答表明了这一点。