C++ 如何初始化不同大小数组的映射?

C++ 如何初始化不同大小数组的映射?,c++,arrays,dictionary,constexpr,static-assert,C++,Arrays,Dictionary,Constexpr,Static Assert,简单的问题是,如何初始化不同大小的数组(或其他容器类型)的映射?例如: enum class code {A,B,C}; enum class res {X1,X2,X3,X4,X5}; std::map<code, ?> name { {code:A, {res::X1,res::X2}}, {code:B, {res::X2,res::X3, res::X4}}, {code:C, {res::X5}} }; 因为validate是一个constep

简单的问题是,如何初始化不同大小的数组(或其他容器类型)的映射?例如:

enum class code {A,B,C};
enum class res {X1,X2,X3,X4,X5};

std::map<code, ?> name {
    {code:A, {res::X1,res::X2}},
    {code:B, {res::X2,res::X3, res::X4}},
    {code:C, {res::X5}}

};
因为
validate
是一个
constepr
基本数组可以工作,但是如何在map参数中将它定义为
res
类型的数组呢?每个阵列的大小可能不同


所以,我犯了一个错误。我的印象是,可以通过constexpr函数访问map。你能建议我使用什么样的容器类型来实现我上面写的内容

如果可以将数组设置为常量,则可以执行以下操作:

std::map<code, std::initializer_list<res>> name {
    {code::A, {res::X1,res::X2}},
    {code::B, {res::X2,res::X3, res::X4}},
    {code::C, {res::X5}}
};
std::映射名称{
{code::A,{res::X1,res::X2},
{code::B,{res::X2,res::X3,res::X4},
{code::C,{res::X5}
};
如果需要能够写入阵列,则需要以下内容:

std::map<code, std::vector<res>> name {
    {code::A, {res::X1,res::X2}},
    {code::B, {res::X2,res::X3, res::X4}},
    {code::C, {res::X5}}
};
std::映射名称{
{code::A,{res::X1,res::X2},
{code::B,{res::X2,res::X3,res::X4},
{code::C,{res::X5}
};
这将以额外的内存分配为代价,因为向量是在堆上分配的

如果您希望它是可写的,并且可以使用固定大小,这也可以工作,并避免额外的分配:

std::map<code, std::array<res, 3>> name {
    {code::A, {res::X1,res::X2}},
    {code::B, {res::X2,res::X3, res::X4}},
    {code::C, {res::X5}}
};
std::映射名称{
{code::A,{res::X1,res::X2},
{code::B,{res::X2,res::X3,res::X4},
{code::C,{res::X5}
};
至于你问题的第二部分,我不太确定是否有任何解决方案能起作用,因为你不能在constexpr函数中访问map。

你不能在constexpr表达式中使用
std::map
,尤其是因为它有一个非平凡的析构函数(
~map();


如果您在标准的
map
部分搜索constexpr,您将找不到它(),而在
std::array
()由于
std::map
不能用在
constepr
表达式中,我不得不找到另一个解决方案,感谢@kfsone和@H.Guijt指出了这一点,并提到了
std::initializer\u list
std::array
,这使我找到了这个解决方案

由于问题中地图中的数据是常量,因此我可以不使用关联容器。因此,我使用了一个排序数组
std::initializer\u list
s以及一个
constepr
实现的find函数,它非常适合我的需要

template <class It, class T>
inline constexpr It sfind (It begin, It end, T const& value) noexcept
{
    return ! (begin != end && *begin != value)? begin : sfind (begin+1, end, value);
}

enum class code {A,B,C};
enum class res {X1,X2,X3,X4,X5};

constexpr std::array<std::initializer_list<res>, 3> name {{
    {res::X1,res::X2}, //code::A
    {res::X2,res::X3, res::X4}, //code::B
    {res::X5} // code::C

}};
const code c = code::A;
const res r = res::X3;
static_assert (name[static_cast<int>(c)].end () - sfind(name[static_cast<int>(c)].begin(), name[static_cast<int>(c)].end(), r) != 0,"Not found");
模板
inline constexpr It sfind(它开始、结束、T const&value)无异常
{
返回!(开始!=结束和开始!=值)?开始:sfind(开始+1,结束,值);
}
枚举类代码{A,B,C};
枚举类res{X1,X2,X3,X4,X5};
constexpr std::数组名称{{
{res::X1,res::X2},//代码::A
{res::X2,res::X3,res::X4},//代码::B
{res::X5}//代码::C
}};
常量代码c=代码::A;
常数r=res::X3;
static_assert(name[static_cast(c)].end()-sfind(name[static_cast(c)].begin(),name[static_cast(c)].end(),r)!=0,“未找到”);

std::map?为什么不
std::vector
?还要注意,它是
code::B
res::X1
不是
code:B
res:X1
。Ma不好。在这里写代码。正如我所知,向量不能从constexpr函数访问。另外,我已经尝试过了,并且得到了对非constexpr函数调用的错误
。您不能在constexpr中使用std::map。就这点而言,不是std::vector。嗯,如果我错了,请纠正我,但映射中的
std::initializer\u list
是否指向表达式结束后不再存在的元素?@NathanOliver这是一个很好的问题。我的印象是这是允许的,但如果你是对的,我迫切需要重写一些代码…不知道关于
std::initializer\u list
。这很有帮助。谢谢
template <class It, class T>
inline constexpr It sfind (It begin, It end, T const& value) noexcept
{
    return ! (begin != end && *begin != value)? begin : sfind (begin+1, end, value);
}

enum class code {A,B,C};
enum class res {X1,X2,X3,X4,X5};

constexpr std::array<std::initializer_list<res>, 3> name {{
    {res::X1,res::X2}, //code::A
    {res::X2,res::X3, res::X4}, //code::B
    {res::X5} // code::C

}};
const code c = code::A;
const res r = res::X3;
static_assert (name[static_cast<int>(c)].end () - sfind(name[static_cast<int>(c)].begin(), name[static_cast<int>(c)].end(), r) != 0,"Not found");