如何将元组插入地图?

时间:2018-01-25 13:58:46

标签: c++ iterator tuples c++14 std-pair

我正在写一个zip_iterator(为了好玩/学术/“哦,没有提升是邪恶的,我们不想要它”的原因)我设想的一个用例是压缩两个vector s一起进入另一个容器,例如map。这在Clang上使用libc ++,但在MSVC2017和GCC 7.2上意外失败。我把问题减少到了这段代码:

#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.);
}

Clang here的工作演示,GCC hereMSVC here的详细演示。

这样可以优雅地使用zip_iterator无效:

std::copy(zip_begin(ints, doubles), zip_end(ints, doubles), std::inserter(int_double_map, int_double_map.begin()));

正如我现在所见zip_iterator here for the full code

我希望这可以工作,因为元组是一个2对元素,一个应该可以从另一个构造。如果我试图找到一个泛型对(元组)构造函数,或者一个元组来配对隐式转换,我似乎找不到一个。那么问题就变成了:为什么它对Clang / libc ++起作用呢?

注意:我不能只在那里推std::make_pair,因为它是通用代码。

一种可能的解决方法是特殊情况下使用双迭代器案例来生成pair而不是tuple。看起来很难看,但可行。如果可能的话,我宁愿避免这样做。

1 个答案:

答案 0 :(得分:4)

  

,一个应该可以从另一个

构建
  • std::pair<T, U>未定义来自std::tuple<T, U>的任何隐式构造函数。

  • 同样,std::tuple<T, U>没有 将任何隐式转换运算符定义为std::pair<T, U>

我认为Clang(libc ++)在这里是不正确的,并且GCC和MSVC是正确的。

  

似乎丑陋,但可行

这不是太糟糕:

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)...);
    } 
}

在C ++ 14中,您可以使用专精/ if constexprstatic_if替换enable_if