将一个参数包转换成另一个?

Converting one parameter pack into another?

我想将迭代器类型的参数包转换为相应的引用参数包。这是我到目前为止得到的:

template <class Iterator, class... Iterators>
class cast_iterators_to_references
{
    using head_reference_type = std::iterator_traits<Iterator>::reference

    // TODO
    //using type = ;
};

我从哪里获取它?

我这样做的原因是要创建一个 "view" 对象。它包含指向它引用的容器的迭代器元组。我想要一个 returns 某个索引处的元素元组的方法,以便我可以为其创建自定义迭代器,创建开始和结束方法,并在基于范围的 for 语句中使用它。

使用方法如下:

template<class Iterators...>
tuple_iterator
{
public:
    using tuple_type = std::tuple<Iterators...>;
    using references = cast_iterators_to_references<Iterators...>;
    using tuple_element_type = std::tuple<references>;

    // ... construct from tuple, copy/move constructors, copy/move assignment etc.

    tuple_element_type operator[](size_t index)
    {
        tuple_element_type element;
        for (size_t i = 0; i < sizeof...(Iterators); i++)
            std::get<i>(element) = std::get<i>(data_)[offset_ + index];

        return element;
    }

    // ... increment, decrement operators etc.

private:
    tuple_type data_;
    size_t offset_;
}

参数包不是first-class,所以处理起来有点麻烦。

cast_iterators_to_references 元功能的第一个尝试可能是这样的:

// Not defined, used to wrap a pack into a type
template <class...> struct pack;

template <class... Iterators>
using cast_iterators_to_references = pack<
    typename std::iterator_traits<Iterators>::reference...
>;

但是你需要助手 classes 来通过模式匹配解压 pack :

template <class> unpack_to_tuple;

template <class... Ts> unpack_to_tuple<pack<Ts...>> {
    using type = std::tuple<Ts...>;
};

// In your class
using references = cast_iterators_to_references<Iterators...>;
using tuple_element_type = typename unpack_to_tuple<references>::type;

所以你最好直接使用参数包:

using tuple_element_type = std::tuple<
    typename std::iterator_traits<Iterators>::reference...
>;

你的operator[]可以这样写:

template <std::size_t... Idx>
auto access(size_t index, std::index_sequence<Idx...>) {
    return std::tie(std::get<Idx>(data_)[index + offset_]...);
}

tuple_element_type operator[](size_t index)
{
    return access(index, std::index_sequence_for<Iterators...>{});
}