【问题标题】:Converting a std::tuple to a std::set将 std::tuple 转换为 std::set
【发布时间】:2015-08-04 19:42:30
【问题描述】:

我正在尝试将 std::tuple 转换为 std::set。我有以下代码

template <typename... T>
auto to_set(std::tuple<T...> const &t) {
  return to_set_helper(t, std::index_sequence_for<T...>{});
}

template <typename T, size_t... Is>
auto to_set_helper(T&& t, std::index_sequence<Is...>) {
  using set_t = typename std::tuple_element<0, 
                      typename std::remove_reference<T>::type>::type;
  std::set<set_t> ret;
  ret.insert(std::get<Is>(t))...;
  return ret;
}

编译器抱怨为该行解包参数包

ret.insert(std::get<Is>(t))...;

我看不出这里有什么问题。

【问题讨论】:

    标签: c++ c++11 variadic-templates c++14 stdtuple


    【解决方案1】:

    这个:

    ret.insert(std::get<Is>(t))...;
    

    不是参数包扩展的有效上下文。很遗憾。但是有一些方法可以做你想做的事情:

    这是标准的扩展技巧:

    using expander = int[];
    expander{0,
        (void(ret.insert(std::get<Is>(t))), 0)...
        };
    

    或者你可以仅仅依靠set可以用initializer_list构造的事实:

    return std::set<ret_t>{std::get<Is>(t)...};
    

    (可能需要附加一个static_cast 以确保所有元素都返回一个ret_t

    【讨论】:

    • 你知道为什么原来的不行,而扩展器可以吗?
    • @subzero 因为原来是“不是参数包扩展的有效上下文”。对于另外两个,initializer-list 一个有效的上下文。
    猜你喜欢
    • 2022-01-11
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多