Consider the following code (also available here on compiler explorer)
#include <utility>
#include <type_traits>
template <std::size_t N, class = std::make_index_sequence<N>>
struct type;
template <std::size_t N, std::size_t... I>
struct type<N, std::index_sequence<I...>>
: std::integral_constant<std::size_t, I>... {
using std::integral_constant<std::size_t, I>::operator()...;
};
using x = type<4>;
For many compilers, it leads to a compiler error:
// icc 19.0.0: <source>(10): error: parameter pack "I" was referenced but not expanded
// icc 19.0.1: OK
// gcc 6.4: <source>:10:60: error: parameter packs not expanded with '...'
// gcc 7.1: OK
// clang 3.9.1: <source>:10:11: error: using declaration contains unexpanded parameter pack 'I'
// clang 4.0.0: OK
// msvc 19.22: <source>(10): error C3520: 'I': parameter pack must be expanded in this context
// msvc 19.23: OK
To me, it seems like perfectly valid c++17
code but I am surprised that it does not seem to compile on relatively recent compilers (especially for intel
and msvc
) (even if it compiles on all the most recent versions).
I am wondering whether:
- it's completely
c++17
valid code and it just took a long time for some vendors to implement it - it is not purely
c++17
valid code