
Hi, While working on improving of implementation of data driven tests, I found rather annoying bug in MSVC-12.0 with variadic templates. The code seems to work fine with msvc-14.0, gcc 4.8 and clang 3.4. I did not try msvc- 13.0. Does anyone know a workaround? Example follows (try to comment on/off line: auto const& t3). Gennadiy // C++ 14 index_sequence template <std::size_t... Ns> struct index_sequence {}; template<typename IS1, typename IS2> struct merge_index_sequence; template <std::size_t... Ns1, std::size_t... Ns2> struct merge_index_sequence<index_sequence<Ns1...>, index_sequence<Ns2...>> { typedef index_sequence<Ns1..., Ns2...> type; }; template <std::size_t B, std::size_t E, typename Enabler = void> struct make_index_sequence { typedef typename merge_index_sequence< typename make_index_sequence<B, (B + E)/2>::type, typename make_index_sequence<(B + E)/2, E>::type>::type type; }; template <std::size_t B, std::size_t E> struct make_index_sequence<B, E, typename std::enable_if<E == B + 1, void>::type> { typedef index_sequence<B> type; }; template <typename... T> using index_sequence_for = typename make_index_sequence<0, sizeof...(T)>::type; ////////////////////////////////////////////////////////////////////////// template<typename T1, typename T2> struct merged_tuple { typedef std::tuple<T1,T2> type; typedef std::tuple<T1 const&,T2 const&> ref; }; template<typename T1, typename ...T> struct merged_tuple<T1, std::tuple<T...>> { typedef std::tuple<T1, T...> type; typedef std::tuple<T1 const&, T const&...> ref; }; template<typename ...T, typename T1> struct merged_tuple<std::tuple<T...>, T1> { typedef std::tuple<T..., T1> type; typedef std::tuple<T const&..., T1 const&> ref; }; template<typename ...T1, typename ...T2> struct merged_tuple<std::tuple<T1...>, std::tuple<T2...>> { typedef std::tuple<T1..., T2...> type; typedef std::tuple<T1 const&..., T2 const&...> ref; }; template<typename ...T1, typename ...T2, std::size_t ...I1, std::size_t ...I2> inline typename merged_tuple<std::tuple<T1...>, std::tuple<T2...>>::ref tuple_merge_impl( std::tuple<T1 const&...> const& a1, std::tuple<T2 const&...> const& a2, index_sequence<I1...> const& , index_sequence<I2...> const& ) { using ref_type = typename merged_tuple<std::tuple<T1...>, std::tuple<T2...>>::ref; return ref_type( std::get<I1>(a1)..., std::get<I2>(a2)... ); } template<typename ...T1, typename ...T2> inline typename merged_tuple<std::tuple<T1...>, std::tuple<T2...>>::ref tuple_merge_impl( std::tuple<T1 const&...> const& a1, std::tuple<T2 const&...> const& a2 ) { return tuple_merge_impl( a1, a2, index_sequence_for<T1...>{}, index_sequence_for<T2...>{} ); } template<typename T> inline std::tuple<T const&> as_tuple( T const& arg ) { return std::tuple<T const&>( arg ); } template<typename ...T> inline std::tuple<T...> const& as_tuple( std::tuple<T...> const& arg ) { return arg; } template<typename T1, typename T2> inline typename merged_tuple<T1, T2>::ref tuple_merge( T1 const& a1, T2 const& a2 ) { return tuple_merge_impl( as_tuple( a1 ), as_tuple( a2 ) ); } int main() { auto const& t1 = tuple_merge( 1, 2 ); auto const& t2 = tuple_merge( 3, 4 ); auto const& t3 = tuple_merge( t1, 5 ); auto const& t4 = tuple_merge( 6, t2 ); return 0; }