简体   繁体   English

在编译时确保特定的 std::array 位置

[英]Ensure specific std::array position at compile time

I have an std::array with entries I want at a specific position according to the index of my Variable class at compile time:根据编译时我的Variable类的index ,我有一个std::array其中包含我想要的特定位置的条目:

#include <string_view>
#include <array>

struct Variable
{
  size_t index;
  std::string_view name;
}

constexpr std::array<Variable, 3> myarray {{{0, "myvar1"},
                                            {1, "myvar2"},
                                            {2, "myvar3"}}};

Now I can ensure the position at compile time with a static assert:现在我可以在编译时使用静态断言确保位置:

static_assert(myarray[0].index == 0);
static_assert(myarray[1].index == 1);
static_assert(myarray[2].index == 2);

This avoids typing errors as:这避免了输入错误,因为:

constexpr std::array<Variable, 3> myarray {{{0, "myvar1"},
                                            {2, "myvar2"}, // wrong index for array position 1
                                            {2, "myvar3"}}};

But this is error prone and violates the principle of "single source of truth".但这很容易出错,并且违反了“单一数据源”的原则。 What I want is for example the reverse of std::get<T> :例如,我想要的是std::get<T>的反向:

constexpr std::size_t index0 = 0;
std::set<index0>(myarray, {index0, "singen"});

But this does not exist, how would I achieve this in C++17?但这不存在,我将如何在 C++17 中实现这一目标?

you might use std::get for your hypothetical std::set<index0>(myarray, {index0, "singen"}) :您可以将std::get用于假设的std::set<index0>(myarray, {index0, "singen"})

constexpr std::size_t index0 = 0;
std::get<index0>(myarray) = {index0, "singen"};

But seems simpler to rework your array creation:但重新创建数组似乎更简单:

constexpr std::array<Variable, 3> make_myarray()
{
    std::array<Variable, 3> res{};
    std::array<std::string_view, 3> strings = {"myvar1", "myvar2", "myvar3"};

    for (std::size_t i = 0; i != res.size(); ++i) {
        res[i] = {i, strings[i]};
    }
    return res;
}

And then进而

constexpr std::array<Variable, 3> myarray = make_myarray();

Demo演示

You might even create lambda instead of regular function and call it directly:您甚至可以创建 lambda 而不是常规函数并直接调用它:

constexpr std::array<Variable, 3> myarray = [](){
    std::array<Variable, 3> res{};
    std::array<std::string_view, 3> strings = {"myvar1", "myvar2", "myvar3"};

    for (std::size_t i = 0; i != res.size(); ++i) {
        res[i] = {i, strings[i]};
    }
    return res;
}();

Demo演示

or even create your check function甚至创建您的检查功能

template <std::size_t N>
constexpr bool is_valid(const std::array<Variable, N>& a) {
    for (std::size_t i = 0; i != a.size(); ++i) {
        if (a[i].index != i) {
            return false;
        }
    }
    return true;
}

constexpr std::array<Variable, 3> myarray {{{0, "myvar1"},
                                            {2, "myvar2"}, // wrong index for array position 1
                                            {2, "myvar3"}}};

static_assert(is_valid(myarray)); // Trigger here.

Demo演示

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

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