The following example code doesn't compile with icc 14.0.2 in C++11 mode, although it seems to be standard compliant code (and both g++ 4.8.1 and clang++ compile it without complaint).
This may or may not be related to https://software.intel.com/en-us/forums/topic/500790 / DPD200252873, but I couldn't really figure out what causes the problems. It might be a name-lookup issue with helper templates being lookup up in the wrong namespaces, or the variadic templates in general. I couldn't really narrow it down any further...
The first version in main.cpp that directly calls the internal function from the THDetail-namespace seems to work, the public one in TH:: which does exactly the same thing is not found or otherwise causes unhappiness.
/*> icc -v icc version 14.0.2 (gcc version 4.8.0 compatibility)> icc --std=c++11 yet_another_icc_bug.cpp yet_another_icc_bug.cpp(53): error: no instance of function template "TH::GetEveryNthElement" matches the argument list argument types are: (std::tuple<int, double, float>) auto t0 = TH::GetEveryNthElement<1u, 0u>(t2); // no work ^ compilation aborted for yet_another_icc_bug.cpp (code 2) Same code compiles fine with g++ or clang++. May (or not) be related to https://software.intel.com/en-us/forums/topic/500790 / DPD200252873. */ #include <tuple> #include <type_traits> #include <utility> namespace TH { template<unsigned ...Is> struct Indices { }; template<unsigned N, unsigned ...Is> struct BuildIndices : BuildIndices<N-1, N-1, Is...> { }; template<unsigned ...Is> struct BuildIndices<0, Is...> : Indices<Is...> { }; template<typename T> using Value = typename std::remove_cv<typename std::remove_reference<T>::type>::type; template<typename Tuple> using IndicesForTuple = BuildIndices<std::tuple_size<Value<Tuple> >::value>; namespace THDetail { template<unsigned N, unsigned Offset, typename Tuple, unsigned ...Is> inline auto GetEveryNthElementImpl(Tuple &&t, Indices<Is ...>) -> decltype(std::tuple<typename std::tuple_element<Offset + N * Is, Value<Tuple> >::type ...>( std::get<Offset + N * Is>(std::forward<Tuple>(t)) ...)) { static_assert(N >= 1u, "Index-multiplier smaller than 1!"); return std::tuple<typename std::tuple_element<Offset + N * Is, Value<Tuple> >::type ...>( std::get<Offset + N * Is>(std::forward<Tuple>(t)) ...); } } // end namespace THDetail template<unsigned N, unsigned Offset = 0u, typename Tuple> inline auto GetEveryNthElement(Tuple &&t) -> decltype(THDetail::GetEveryNthElementImpl<N, Offset>(std::forward<Tuple>(t), BuildIndices<(std::tuple_size<Value<Tuple> >::value - Offset + N - 1u) / N>())) { static_assert(Offset < N, "Offset is larger than index-multiplier!"); return THDetail::GetEveryNthElementImpl<N, Offset>(std::forward<Tuple>(t), BuildIndices<(std::tuple_size<Value<Tuple> >::value - Offset + (N - 1u)) / N>()); } template<unsigned N, unsigned Offset, typename Tuple> using TupleEveryNthElement = decltype(GetEveryNthElement<N, Offset, Tuple>(std::declval<Tuple>())); } // end namespace TH int main(int argc, char const *argv[]) { std::tuple<int, double, float> t2; auto tm1 = TH::THDetail::GetEveryNthElementImpl<1u, 0u>(t2, TH::BuildIndices<(std::tuple_size<decltype(t2)>::value - 0u + (1u - 1u)) / 1>()); // works auto t0 = TH::GetEveryNthElement<1u, 0u>(t2); // no work return 0; }