迭代一个元组......再次

时间:2015-02-15 21:32:09

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

我一直在做C ++,但我不熟悉模板。

最近,我尝试编写一个包装std::vector<std::tuple<Types...>>的类。这个类必须有成员函数,我真的需要能够迭代而不是元组。事实上,如果我能够打印元组的每个元素(按顺序),我将能够做我需要的一切。

我找到了一个使用演员表的解决方案,但我对此并不十分自信,因为它基于我不太喜欢的演员阵容(另外,当我尝试使用{{1}时},它不再编译了。)

我的问题是,下面的代码是正确的,可移植的,它是一个黑客,我应该找到另一种方法来做这个比使用这个演员吗?此外,这个演员可能是运行时演员吗?没有这个,有没有办法做我想做的事?

static_cast

提前感谢您的回答。

2 个答案:

答案 0 :(得分:11)

使用std::index_sequence_for获取乐趣和利润。

template <typename TupleLike, size_t ... Inds>
std::ostream& PrintHelper(std::ostream& out, TupleLike const& tuple, std::index_sequence<Inds...>)
{
  int unused[] = {0, (void(out << std::get<Inds>(tuple) << " "), 0)...};
  (void)unused;
  return out;
}

template<typename... Types>
std::ostream& operator<<(std::ostream& out, std::tuple<Types...> const& tuple)
{
  return PrintHelper(out, tuple, std::index_sequence_for<Types...>());
}

编辑:Live Demo。感谢@dyp。这使用this answer的扩展技巧。

答案 1 :(得分:0)

我找到了另一种方法来做我想做的事。我使用this article可以按降序打印元组的元素,我使用第二个索引J == std::tuple_size<std::tuple<Types...>>::value - I,这样我就可以在I==0时专门化模板。

template<std::size_t I, std::size_t J, typename... Types>
struct printHelper
{
    std::ostream& operator()(std::ostream& out, std::tuple<Types...> const& tuple)
    {
        out << std::get<J>(tuple) << " ";

        // Recursive call without cast
        return printHelper<I-1,J+1,Types...>{}(out, tuple);
    };
};

// Specialization on the last element when I==0
template<std::size_t J, typename... Types>
struct printHelper<0,J,Types...>
{
    std::ostream& operator()(std::ostream& out, std::tuple<Types...> const& tuple)
    {
        // Nothing to do here
        return out;
    }
};

template<typename... Types>
std::ostream& operator<<(std::ostream& out, std::tuple<Types...> const& tuple)
{
    return printHelper<std::tuple_size<std::tuple<Types...>>::value, 0, Types...>{}(out, tuple);
}