【发布时间】:2019-02-15 16:33:23
【问题描述】:
我可以写这个,而且效果很好:
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 正是我想要的。
无论如何,我很想得到任何想法。
【问题讨论】:
-
您添加一个将 std::array<:pair>> 作为输入的 ctor,这样您就可以使用初始化列表初始化数组
-
@Claudiu Guiman,
std::array<Whatever, Count>将无法从初始化列表中推导出Count。这:C++ template<size_t Count> void test(std::array<int, Count>) {} int main() { test({1,2,3}); }给出了 ``` prog.cc:45:3: 错误:没有匹配的函数用于调用 'test' test({1,2,3}); ^~~~ prog.cc:41:6:注意:候选模板被忽略:无法推断模板参数'Count' void test(std::array) {} `` -
是的,你是对的——出于某种奇怪的原因,我把它与 std::vector 混淆了。顺便说一句,我知道这不是你问的,但也许你可以使用 std::vector 代替数组?
-
@Claudiu Guiman,用于运行时初始化——当然。但我希望它在编译时使用
constexpr进行初始化。尽管std::initializer_list在 C++17 中拥有所有成员constexpr,包括size(),但我不知道如何使其能够定义Count模板参数。 -
stackoverflow.com/questions/8192185/… 您可以使用两组花括号初始化 std::array: std::array<:string> strings = {{ "a", "b" } };
标签: c++ templates c++17 variadic-templates