[英]How to insert a tuple into a map?
I was writing a zip_iterator
(for fun/academic/"oh noes Boost is evil we don't want it" reasons) and one of the use cases I envisioned is zipping two vector
s together into another container, such as a map
. 我正在写一个zip_iterator
(为了好玩/学术/“哦,没有Boost是邪恶的,我们不想要它”的原因)我设想的一个用例是将两个vector
一起压缩到另一个容器中,例如map
。 This worked on Clang with libc++, but failed unexpectedly on MSVC2017 and GCC 7.2. 这在Clang上使用libc ++,但在MSVC2017和GCC 7.2上意外失败。 I reduced the problem to this code: 我把问题减少到了这段代码:
#include <iterator>
#include <map>
#include <tuple>
int main()
{
std::map<int, double> map;
auto it = std::inserter(map, map.begin());
it = std::make_tuple(1, 1.);
}
Working demo for Clang here , broken demo's for GCC here and MSVC here . 这里是Clang的工作演示, 这里是GCC的破解演示和MSVC 。
This makes elegant use of my zip_iterator
not work: 这使我优雅地使用我的zip_iterator
不起作用:
std::copy(zip_begin(ints, doubles), zip_end(ints, doubles), std::inserter(int_double_map, int_double_map.begin()));
See here for the full code of that zip_iterator
as I have it now. 请参阅此处获取该 zip_iterator
的完整代码 ,因为我现在拥有它。
I expect this to work because a tuple is a 2-pair element and one should be constructible from the other. 我希望这可以工作,因为元组是一个2对元素,一个应该可以从另一个构造。 If I try to find a generic pair(tuple) constructor, or a tuple to pair implicit conversion, I can't seem to find one. 如果我试图找到一个泛型对(元组)构造函数,或者一个元组来配对隐式转换,我似乎找不到一个。 So then the question becomes: why does it work on Clang/libc++ at all? 那么问题就变成了:为什么它对Clang / libc ++起作用呢?
Note: I can't just shove an std::make_pair
in there, because, well, it's generic code. 注意:我不能只在那里推一个std::make_pair
,因为它是通用代码。
A possible workaround would be to special-case the two-iterator case to produce a pair
instead of a tuple
. 一种可能的解决方法是特殊情况下使用双迭代器来生成一pair
而不是tuple
。 Seems ugly, but doable. 看起来很难看,但可行。 I'd rather avoid that if at all possible. 如果可能的话,我宁愿避免这样做。
and one should be constructible from the other 一个应该是另一个可以构建的
std::pair<T, U>
does not define any implicit constructor from std::tuple<T, U>
. std::pair<T, U>
没有定义来自std::tuple<T, U>
任何隐式构造函数。
Similarly, std::tuple<T, U>
does not define any implicit conversion operator to std::pair<T, U>
. 类似地, std::tuple<T, U>
没有为std::pair<T, U>
定义任何隐式转换运算符。
I think Clang (libc++) is incorrect here, and that GCC and MSVC are correct. 我认为Clang(libc ++)在这里是不正确的,并且GCC和MSVC是正确的。
Seems ugly, but doable 看起来很难看,但可行
It's not too bad: 这不是太糟糕:
template <typename... Ts>
auto make_thing(Ts&&... xs)
{
if constexpr(sizeof...(xs) == 2))
{
return std::make_pair(std::forward<Ts>(xs)...);
}
else
{
return std::make_tuple(std::forward<Ts>(xs)...);
}
}
In C++14, you can replace if constexpr
with specialization/ enable_if
or static_if
. 在C ++ 14中,您可以使用specialization / enable_if
或static_if
替换if constexpr
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.