[英]Compile-time matrix template type
我正在尝试获得一段我编写的代码,以实现有趣的工作。 基本上,我想生成一个在编译时给定的类型 :一个矩阵。
例如,我希望abstract_matrix
如下所示:
template <std::size_t r, std::size_t c, class T = double>
class abstract_matrix
{
public:
static const std::size_t rows = r;
static const std::size_t cols = c;
typedef T value_type;
typedef T storage_type[rows][cols];
constexpr abstract_matrix(storage_type items)
{
// I hope it's not needed
}
storage_type storage;
};
然后,我想按照以下方式实际创建带有魔术的具体类型:
constexpr static const int vals[3][3] {
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 }
};
// do magic here for the vals parameter to make this compile
using id_3by3 = abstract_matrix<3, 3, vals, int>;
// use the generated type
id_3by3 mymatrix;
auto matrix = mymatrix * ...;
您对如何在编译时将这些值“ 注入 ”模板并生成适当的类型有任何建议吗? 该类型中的所有内容都是static
, const
和constexpr
。
谢谢!
您可以使其工作,但必须考虑一些事项。
vals
可以作为非类型参数传递。 但是,它必须在T
之后。 否则,参数的基本类型未知。
结果,没有默认值T
您可能会继续将T
默认值设为double
,将最后一个参数的默认值设为nullptr
但这会导致代码混乱。
id_3by3
定义需要使用&vals
,而不仅仅是vals
。
如果将vals
定义为const
,则非类型模板参数还必须在其类型中使用const
。
const int vals[3][3] { ... };
您使用的命令
template <std::size_t r, std::size_t c, class T, T const(*v)[r][c] > class abstract_matrix { ... };
如果您希望能够修改矩阵的内容,则需要使用:
template <std::size_t r, std::size_t c, class T, T (*v)[r][c]> class abstract_matrix { ... };
您使用哪个指令
int vals[3][3] { ... };
这是一个工作程序:
#include <iostream>
#include <cstdint>
template <std::size_t r, std::size_t c, class T , T (*v)[r][c]>
class abstract_matrix
{
public:
static const std::size_t rows = r;
static const std::size_t cols = c;
typedef T value_type;
constexpr static T(&vals)[r][c] = *v;
constexpr abstract_matrix()
{
}
};
int vals[3][3] {
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 }
};
using id_3by3 = abstract_matrix<3, 3, int, &vals>;
int main()
{
id_3by3 mymatrix;
// Original matrix.
for ( size_t i = 0; i < id_3by3::rows; ++i )
{
for ( size_t j = 0; j < id_3by3::cols; ++j )
{
std::cout << id_3by3::vals[i][j] << " ";
id_3by3::vals[i][j]++;
}
std::cout << "\n";
}
std::cout << "\n";
// Modified matrix.
for ( size_t i = 0; i < id_3by3::rows; ++i )
{
for ( size_t j = 0; j < id_3by3::cols; ++j )
{
std::cout << id_3by3::vals[i][j] << " ";
}
std::cout << "\n";
}
}
输出:
1 0 0
0 1 0
0 0 1
2 1 1
1 2 1
1 1 2
更新,以回应OP的评价
您可以使用static int vals[3][3] = { ... };
当您希望能够定义.h文件的类型并在多个.cpp文件中使用它时。
我可以在多个.cpp文件中使用具有以下内容的.h文件。
#pragma once
#include <cstdint>
template <std::size_t r, std::size_t c, class T , T (*v)[r][c]>
class abstract_matrix
{
public:
static const std::size_t rows = r;
static const std::size_t cols = c;
typedef T value_type;
constexpr static T(&vals)[r][c] = *v;
constexpr abstract_matrix()
{
}
};
static int vals[3][3] {
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 }
};
using id_3by3 = abstract_matrix<3, 3, int, &vals>;
仍然可以通过将这些行分成两个.h文件来改进。 例如,您可以使用:
abstract_matrix.h:
#pragma once
#include <cstdint>
template <std::size_t r, std::size_t c, class T , T (*v)[r][c]>
class abstract_matrix
{
public:
static const std::size_t rows = r;
static const std::size_t cols = c;
typedef T value_type;
constexpr static T(&vals)[r][c] = *v;
constexpr abstract_matrix()
{
}
};
id_3by3.h:
#include "abstract_matrix.h"
static int vals[3][3] {
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 }
};
using id_3by3 = abstract_matrix<3, 3, int, &vals>;
这样一来,您就可以在不同的.h文件中定义其他类似于id_3by3
类型,而无需在所有文件中重复abstract_matrix
的定义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.