c++ - 具有枚举特定实现和共享功能 (CRTP) 的类模板
问题描述
我想设计一个Matrix
允许指定内存管理方法的类,即
Matrix<Allocator::vector, int> mv(2, 2);
Matrix<Allocator::unique_pointer, int> mu(2, 2);
mv(1, 1) = 1;
mu(1, 2) = 1;
尽管内存策略不同,mv
但mu
彼此兼容(即当我重载“+”运算符时)。
我已经从具有共享功能的类模板专业化中找到了非常好的帮助,这对 n 维向量类也是如此。
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> {
private:
std::vector<T> data_;
};
template <typename T>
T& Matrix<Allocator::vector, T>::at(size_t i, size_t j) {
return data_[i * rows() + j];
}
template <typename T>
class Matrix<Allocator::unique_pointer, T> : public MatrixBase<T> {
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 * rows() + j];
}
不幸的是,编译器抱怨
./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];
我认为错误源于
template <typename T>
class Matrix<Allocator::vector, T> : public MatrixBase<T> {
private:
std::vector<T> data_;
};
我该如何解决?
解决方案
将定义移到里面就可以解决问题了。这个问题是由于范围界定造成的。
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_;
};
考虑以下示例
class P {
public:
virtual int test();
};
class C : public P {
};
int C::P:: test() { // if you omit P, it will not compile
return 21;
}
或者你可以在里面重新声明它C
,所以它会在C
's 范围内。
推荐阅读
- groovy - Groovy Power Assert Null 检查
- oracle - oracle 19中的列统计信息?
- c - 宏用作字符串导致字符数组的初始化字符串太长
- intellij-idea - WebStorm (PhpStorm / IntelliJ IDEA) 如何使用自定义 data.json 扩展自动完成功能
- c# - OpenAPI:TypeLoadException,在 dll 文件中找不到类型
- authentication - 对于具有 Oauth 2.0 隐式流程的 Web 应用程序,是否有避免不时询问用户登录的解决方案?
- vue.js - ApexChart 条形图中的条形图覆盖了数据标签
- python - 如何使用 Python 3.8 安装 pip?
- r - 如何在保留其他列类型的同时拆分“data.frame”类型列?
- c# - 通过按顺序选择单个文件打开多个文件 - 从多个文件生成文件名