编译时确保特定的 std::array 位置
Ensure specific std::array position at compile time
我有一个 std::array
,在编译时根据我的 Variable
class 的 index
在特定位置包含我想要的条目:
#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"}}};
现在我可以用静态断言确保编译时的位置:
static_assert(myarray[0].index == 0);
static_assert(myarray[1].index == 1);
static_assert(myarray[2].index == 2);
这样可以避免输入错误:
constexpr std::array<Variable, 3> myarray {{{0, "myvar1"},
{2, "myvar2"}, // wrong index for array position 1
{2, "myvar3"}}};
但是这样容易出错,违反了"single source of truth"的原则。例如,我想要的是 std::get<T>
:
的反转
constexpr std::size_t index0 = 0;
std::set<index0>(myarray, {index0, "singen"});
但这不存在,我如何在 C++17 中实现它?
您可以使用 std::get
作为假设 std::set<index0>(myarray, {index0, "singen"})
:
constexpr std::size_t index0 = 0;
std::get<index0>(myarray) = {index0, "singen"};
但重新创建数组似乎更简单:
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;
}
然后
constexpr std::array<Variable, 3> myarray = make_myarray();
您甚至可以创建 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;
}();
甚至创建您的检查功能
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.
我有一个 std::array
,在编译时根据我的 Variable
class 的 index
在特定位置包含我想要的条目:
#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"}}};
现在我可以用静态断言确保编译时的位置:
static_assert(myarray[0].index == 0);
static_assert(myarray[1].index == 1);
static_assert(myarray[2].index == 2);
这样可以避免输入错误:
constexpr std::array<Variable, 3> myarray {{{0, "myvar1"},
{2, "myvar2"}, // wrong index for array position 1
{2, "myvar3"}}};
但是这样容易出错,违反了"single source of truth"的原则。例如,我想要的是 std::get<T>
:
constexpr std::size_t index0 = 0;
std::set<index0>(myarray, {index0, "singen"});
但这不存在,我如何在 C++17 中实现它?
您可以使用 std::get
作为假设 std::set<index0>(myarray, {index0, "singen"})
:
constexpr std::size_t index0 = 0;
std::get<index0>(myarray) = {index0, "singen"};
但重新创建数组似乎更简单:
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;
}
然后
constexpr std::array<Variable, 3> myarray = make_myarray();
您甚至可以创建 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;
}();
甚至创建您的检查功能
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.