简体   繁体   中英

Variadic template expansion not as expected

I'm using Visual Studio Community 2015, and I'm attempting to implement a parallel vector template. This is a learning exercise for me, as I've yet to master variadic templates. The expansion is not working as expected.

What I expect from get_elems is a tuple of references of the parameter pack types of the corresponding vector indices. What I get is a tuple of only the first type in the parameter pack.

I tested with a parallel_vector<int, char> .

template <typename... Elems>
class parallel_vector
{
    using t_data_type = std::tuple<std::vector<Elems>...>;
    using reference_type = std::tuple < Elems&... >;

    t_data_type data_;

    // Example 1
    // C2440 'return': cannot convert from 'std::tuple<int &>' to 'std::tuple<int &,char &>'
    template <size_t... N>
    auto get_elems(std::index_sequence<N...>, size_t index)
    {
        return std::forward_as_tuple(std::get<N>(data_)[index]...);
    }

    // Example 2
    // C2440 '<function-style-cast>': cannot convert from 'int' to 'std::tuple<int &,char &>'
    template <size_t... N>
    reference_type get_elems(std::index_sequence<N...>, size_t index)
    {
        return reference_type(std::get<N>(data_)[index]...);
    }

public:
    reference_type operator[](size_t index)
    {
        return get_elems(std::index_sequence_for<Elems>{}, index);
    }
};

The errors are in the code comments. These are what I have tried. I presume I have a fundamental misunderstanding of variadic templates. Please advise.

This is ill-formed for using a parameter pack unexpanded:

reference_type operator[](size_t index)
{
    return get_elems(std::index_sequence_for<Elems>{}, index);
    //                                       ^^^^^  
}

which seems to confuse MSVC into thinking that it's actually a single type, so that index_sequence_for<Elems> becomes make_index_sequence<1> which is index_sequence<0> .

The fix is to expand it:

reference_type operator[](size_t index)
{
    return get_elems(std::index_sequence_for<Elems...>{}, index);
    //                                            ^^^  
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM