gpt4 book ai didi

c++ - 编译时矩阵模板类型

转载 作者:行者123 更新时间:2023-11-28 04:56:14 25 4
gpt4 key购买 nike

我正在尝试获取一段我正在编写的代码,以享受工作的乐趣。基本上我想生成一个类型,在编译时给定:一个矩阵。

例如,我希望 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 * ...;

关于如何将这些值“注入(inject)”到模板并在编译时生成正确的类型,您有什么建议吗?类型中的所有内容都是 staticconstconstexpr

谢谢!

最佳答案

您可以让它发挥作用,但有几件事必须考虑。

  1. vals 可以作为非类型参数传递。但是,它需要在 T 之后。否则,参数的基本类型未知。

    因此,T 没有默认值。您可能会继续将 T 的默认值设置为 double,并将最后一个参数的默认值设置为 nullptr,但这会导致代码困惑。

  2. id_3by3的定义需要使用&vals,而不仅仅是vals

  3. 如果将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 文件来改进。例如,您可以使用:

抽象矩阵.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 的定义。

关于c++ - 编译时矩阵模板类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47080515/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com