2015-10-24 183 views
4

下面的代碼編譯和工作,因爲我希望它與叮噹聲和gcc,但給Visual Studio 2015 RTM的錯誤。我認爲clang和gcc是正確的,但我不確定。這個代碼應該編譯?模板參數推導和默認模板參數

#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編譯此行如果我改變運營商+到:

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); 

但我不認爲它應該有必要再次把std::index_sequence<Is...>y

+2

除非我遺漏了某些東西,'decltype(std :: make_index_sequence {})'完全是無意義的,應該是'std :: make_index_sequence '。 – orlp

+0

@orlp好點。不知道我是如何錯過的 - 我正在重構真正的代碼,這是從那裏提取出來的。有趣的是,改變它會讓問題在VS2015中消失。 – mattnewport

+1

那麼這是一個編譯器錯誤,因爲儘管無關緊要,它們應該是等價的。 – orlp

回答

6

IS根本不應該是Vector類型的一部分。相反,使用幫手功能:

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()); 
} 

我沒有訪問VS2015來測試這個,但它應該工作。

+0

這就是我最初的做法。以這種方式重構它有幾個優點。不僅如此,它讓我可以用'constexpr'解決另一個Visual Studio 2015錯誤:-)主要的動機是減少調試版本的內聯深度。 – mattnewport