Outputting template arguments and default template arguments

The code below compiles and works the way I want with clang and gcc, but gives an error with RTM for Visual Studio 2015. I think clang and gcc are correct to allow this, but I'm not sure. Should this code compile?

#include <iostream>
#include <type_traits>
#include <utility>

template <typename T, size_t N, typename IS = decltype(std::make_index_sequence<N>{})>
struct Vector {
    T e_[N];
};

template <typename T, typename U, size_t N, size_t... Is>
constexpr auto operator+(const Vector<T, N, std::index_sequence<Is...>>& x,
                         const Vector<U, N>& y) {
    using V = std::common_type_t<T, U>;
    return Vector<V, N>{x.e_[Is] + y.e_[Is]...};
}

int main() {
    const auto v0 = Vector<float, 4>{1, 2, 3, 4};
    const auto v1 = Vector<float, 4>{5, 6, 7, 8};
    const auto v2 = v0 + v1;
    for (auto x : v2.e_) std::cout << x << ", ";
    std::cout << std::endl;
}

Visual Studio compiles this ok if I change operator + to:

template <typename T, typename U, size_t N, size_t... Is>
constexpr auto operator+(const Vector<T, N, std::index_sequence<Is...>>& x,
                         const Vector<U, N, std::index_sequence<Is...>>& y);

But I do not think that it is necessary to put again std::index_sequence<Is...>for y.

+4
source share
1 answer

ISshould not be part of the type Vectorat all. Instead, use a helper function:

template <typename T, std::size_t N>
struct Vector {
    T e_[N];
};

template <typename T, typename U, std::size_t N, std::size_t... Is>
inline constexpr auto add_impl(const Vector<T, N>& x, const Vector<U, N>& y,
                               std::index_sequence<Is...>) {
    using V = std::common_type_t<T, U>;
    return Vector<V, N>{x.e_[Is] + y.e_[Is]...};
}

template <typename T, typename U, std::size_t N,
          typename Is = std::make_index_sequence<N>>
constexpr auto operator+(const Vector<T, N>& x, const Vector<U, N>& y) {
    return add_impl(x, y, Is());
}

I do not have access to VS2015 to check this out, but it should work.

+6
source

Source: https://habr.com/ru/post/1613058/


All Articles