【发布时间】:2015-09-19 15:14:25
【问题描述】:
我有一个constexpr 键值映射,大致有这个定义:
// map with `pos` remaining entries
template<typename K, typename V, size_t pos>
class Map {
public:
template<class Head, class... Tail>
constexpr Map(Head head, Tail... tail)
:
value{head},
tail{tail...} {}
Element<K, V> value;
const Map<K, V, pos - 1> tail;
// members etc
};
// map end element.
template<typename K, typename V>
class Map<K, V, 0> {
public:
constexpr Map() {}
// end element specifics.
};
为了在编译时初始化一个键值映射,我有一个实用函数来转发元素:
template<typename K, typename V, typename... Entries>
constexpr Map<K, V, sizeof...(Entries)> create_const_map(Entries&&... entry) {
return Map<K, V, sizeof...(entry)>(Entry<K, V>{std::forward<Entries>(entry)}...);
}
Element 定义为:
template<class K, class V>
class Entry {
public:
constexpr Entry(const K &key, const V &value)
:
key{key},
value{value} {}
constexpr Entry(std::pair<K, V> pair)
:
key{pair.first},
value{pair.second} {}
const K key;
const V value;
};
要实际创建地图,我可以成功使用std::make_pair:
constexpr auto cmap = create_const_map<int, int>(
std::make_pair(0, 0),
std::make_pair(13, 37),
std::make_pair(42, 9001)
);
我现在想要的是消除对std::make_pair 的调用并改用大括号:
constexpr auto cmap = create_const_map<int, int>(
{0, 0},
{13, 37},
{42, 9001}
);
但这会导致编译失败,因为 {} 没有被推断为对的构造:
/home/jj/devel/openage/libopenage/datastructure/tests.cpp:191:24: error: no matching function for call to 'create_const_map'
constexpr auto cmap = create_const_map<int, int>(
^~~~~~~~~~~~~~~~~~~~~~~~~~
/home/jj/devel/openage/libopenage/datastructure/constexpr_map.h:286:46: note: candidate function not viable: requires 0 arguments, but 3 were provided
constexpr Map<K, V, sizeof...(Entries)> create_const_map(Entries&&... entry) {
^
我该怎么做才能使用{a, b} 代替std::make_pair(a, b)?
【问题讨论】:
-
代替
Entries的参数包,取一个新模板参数E的initializer_list。 -
create_map和create_const_map是同一个功能吗? -
@DanielJour 是的,我纠正了错字。
-
在不知道 Map 是什么的情况下无法进行实验以更好地理解。我知道 std::map 是什么,但不知道 Map。
-
@mattnewport 不幸的是,他必须将大小作为模板参数传递,但对于 initializer_list,大小不被称为可作为模板参数传递的常量表达式。结果是,也许是为了消除这个尺寸参数。它是用来做什么的?
标签: c++ templates c++11 c++14 variadic-templates