我可以写这个并且它工作得很好:
struct Foo
{
int i;
std::string s;
};
const Foo foo[] = {
{ 42, "the answer to the ultimate questions" },
{ 23 /*initializing only the first member, 's' gets the default value*/ }
};
我想做的是用一个结构来包装数组,这样我就可以向它添加方法:
template<typename V1, typename V2, size_t Count>
struct Map
{
std::array<std::pair<V1, V2>, Count> mappings;
//or
//std::pair<V1, V2> mappings[Count];
V1 operator()(const V2&) const;
V2 operator()(const V1&) const;
};
我想将它初始化为一个未知边界数组,如下所示:
constexpr Map<int, std::string_view, /*???*/> = {
{ 42, "the answer to the ultimate question" },
{ 23, "some other stuff" },
{ /*...*/ }
};
但是随后出现了一个问题,您需要指定我不想做的 Count
模板参数,我希望它像在数组情况下一样工作。
我认为返回此类对象的函数可以解决问题,如下所示:
template<typename V1, typename V2, typename... Args>
constexpr auto makeMap(Args... args)
{
return Map<V1, V2, sizeof...(Args)>{ args... };
}
然后允许像这样使用它:
using Item = std::pair<int, std::string_view>;
constexpr auto map = makeMap<int, std::string_view>(
Item{ 42, "the answer to the ultimate questions" },
Item{ 23, "some other stuff" }
);
但是如果你省略了Item
类型,那么模板实例化就不能推导参数类型,这就禁止了我最初想要的用法:
constexpr auto map = makeMap<int, std::string_view>(
{ 42, "the answer to the ultimate questions" },
{ 23, "some other stuff" }
);
目前我认为这是不可能的,但无论如何我还是想问一下,以防我遗漏了什么。
在研究这个时,我发现了 a proposal这正是我想要的。
无论如何,我很乐意得到任何想法。
最佳答案
使用建议 to_array
:
template<typename V1, typename V2, size_t N>
constexpr auto makeMap(std::pair<V1, V2> const (&a)[N])
{
return Map<V1, V2, N>{ to_array<std::pair<V1, V2>>(a) };
}
constexpr auto map = makeMap<int, std::string_view>({
{ 42, "the answer to the ultimate question" },
{ 23, "some other stuff" },
{ /*...*/ }
});
如果您的编译器支持 library fundamentals TS v2,您可以找到 to_array
的实现在标题中 <experimental/array>
, 在命名空间内 std::experimental
.
关于c++ - 在编译时像未知边界数组一样初始化 C++ 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54713474/