简体   繁体   English

如何在常量 header 文件中声明不同大小列表的编译时常量列表?

[英]How to declare a compile-time constant list of different size lists in a constant header file?

Introduction介绍

Good day,再会,

I want to optimize my application and especially a constant header file.我想优化我的应用程序,尤其是一个常量 header 文件。 In order to do so, I define inline constexpr constants in order to avoid multiple copies of those variable in files they are included.为此,我定义了内联 constexpr 常量,以避免在包含它们的文件中出现这些变量的多个副本。 And also to have compile-time constants.并且还具有编译时常量。

I want now to add a new inline constexpr variable/arrays and this complexifies the constant header files.我现在想添加一个新的内联 constexpr 变量/数组,这会使常量 header 文件复杂化。 I want a list/array of a certain fixed size containing lists/arrays, each of them of different sizes.我想要一个包含列表/数组的某个固定大小的列表/数组,每个列表/数组都有不同的大小。 Finally, I would like an easy way of using it and easy accessibility.最后,我想要一种简单的使用方法和易于访问的方法。


Planned work计划工作

In the following, I note CONST to denot that the CONST values are compile-time constants.在下文中,我注意到 CONST 表示 CONST 值是编译时常量。 I wanted to implement my constant lists/arrays, that are later needed to be contained in a parent list/array (all defined in the constant header file), as:我想实现我的常量列表/数组,稍后需要包含在父列表/数组中(全部在常量 header 文件中定义),如:

inline constexpr std::array<CONST int, size1> first = { some CONST values };
inline constexpr std::array<CONST int, size2> second= { some other CONST values };
inline constexpr std::array<CONST int, size3> third = { some other CONST values };

Now, the idea is to access each array via a parent list for simplicity, if possible:现在,为了简单起见,想法是通过父列表访问每个数组,如果可能的话:

CONTAINER parent = { first, second, third };

Problems问题

Now I see problem arrising when I want to manipulate the arrays.现在,当我想操作 arrays 时,我发现问题出现了。 Ideally, I would like the children (first, second and third) to behave as std::vector<int> and the parent as std::vector<std::vector<CONST int>*>.理想情况下,我希望孩子(第一个、第二个和第三个)表现得像 std::vector<int>,而父母表现得像 std::vector<std::vector<CONST int>*>。 Because I could access first via a std::vector<CONST int>* pointer and I could change the pointed vector like the following:因为我可以首先通过 std::vector<CONST int>* 指针访问,我可以更改指向的向量,如下所示:

// Initialization
std::vector<CONST int>* current_vec = nullptr;
...
// First assignation
current_vec = parent[0];
...
// Reassignation
current_vec = parent[1];
...

But this implementation uses vector.但是这个实现使用向量。 With std::array, I think my pointer could not do the thing because it needs to know the size of each child arrays.使用 std::array,我认为我的指针无法做到这一点,因为它需要知道每个子 arrays 的大小。 Also, maybe I could do something with iterators but same problem (auto keyword might be a solution?).另外,也许我可以用迭代器做一些事情但同样的问题(自动关键字可能是一个解决方案?)。

So, what I did for now is to use std::vector and define the child arrays as:所以,我现在所做的是使用 std::vector 并将子 arrays 定义为:

inline const std::vector<int> first = { some CONST values };
inline const std::vector<int> second = { some other CONST values };
inline const std::vector<int> third = { some other CONST values };

And afterwards, I define the parent as:之后,我将父级定义为:

inline constexpr std::array<const std::vector<CONST int>*, 3> parent = {&first, &second, &third};

I can access the children like expected above:我可以像上面预期的那样访问孩子:

const std::vector<CONST int>* to_access = parent[0];

It seems to work and I think the vectors are compiled-const (I guess so, if not, I wouldn't be able to compile the inline constexpr parent?).它似乎有效,我认为向量是编译的常量(我想是这样,如果不是,我将无法编译内联 constexpr 父级?)。


Question问题

First, do you find the approach meaningful and is there something I don't see know that actually make my solution wrong?首先,您觉得这种方法有意义吗?是否有一些我看不到的东西实际上使我的解决方案出错了? Secondly, would you use another container or another solution with constexpr rather than a const vector, an alternative that I am maybe not aware of (maybe constexpr functions or working with iterators)?其次,您是否会使用另一个容器或另一个解决方案与 constexpr 而不是 const 向量,这是我可能不知道的替代方案(可能是 constexpr 函数或使用迭代器)?

I hope everything is clear.我希望一切都清楚。 I thank you in advance for your advises and help.我提前感谢您的建议和帮助。

Note笔记

I know that we can define constexpr vector since c++20 but I think it works only with the msvc c++20 compiler so I want to avoid that solution.我知道我们可以从 c++20 开始定义 constexpr 向量,但我认为它只适用于 msvc c++20 编译器,所以我想避免这种解决方案。

The following may give you ideas:以下内容可能会给你一些想法:

#include <array>
const int size1 = 1;
const int size2 = 2;
const int size3 = 3;

constexpr std::array<int, size1> first = { 1 };
constexpr std::array<int, size2> second= { 2 };
constexpr std::array<int, size3> third = { 3 };

#include <variant>
// The safest, I guess, annoying to use.
constexpr std::array<
    std::variant<decltype(first), decltype(second), decltype(third)>,
    3> parent1 = {
        first, second, third
};

// The simplest - no bounds information.
constexpr std::array<const int *, 3> parent2 = {
    first.data(), second.data(), third.data()
};

// Tie bounds together with pointers.
constexpr std::array<std::pair<const int *, std::size_t>, 3> parent3 = {{
    { first.data(), first.size(), },
    { second.data(), second.size(), },
    { third.data(), third.size(), },
}};

// In C++20 we now have span
#include <span>
constexpr std::array<std::span<const int>, 3> parent4 = {{
    first, second, third
}};

// Compile-time template access.
template<int index>
constexpr auto parent5() {
    if constexpr (index == 0) {
        return first;
    } else if constexpr (index == 1) {
        return second;
    } else if constexpr (index == 2) {
        return third;
    }
}

I think accessing uniformly 3 arrays with different sizes is asking for out-of-bounds trouble.我认为统一访问 3 个不同大小的 arrays 是在要求越界麻烦。 Remember to check bounds to avoid undefined behavior.请记住检查边界以避免未定义的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM