1

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
Vincent
  • 57,703
  • 61
  • 205
  • 388
  • At least for GCC and Clang, those aren't particularly recent compilers. In fact, those versions seem quite reasonable for when a C++17 feature would be added. Also, do you have any particular reason to think the code is invalid, given that all compilers do accept it currently? – cigien May 09 '22 at 03:07
  • Since the trunks of [all compilers can be successfully compiled](https://godbolt.org/z/YzhKao9on) at present, doesn't it mean that all compilers have fixed bugs, and they all agree that this is a valid c++17 code? So what is the point of this question? – 康桓瑋 May 09 '22 at 03:11
  • @康桓瑋 It could be something coming from a later standard that compiler started to accept as an extension. – Vincent May 09 '22 at 03:17
  • But the compilation flag is using the *C++17 standard*, isn't it? – 康桓瑋 May 09 '22 at 03:21

1 Answers1

1

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

The code is valid but the compiler version you are listing are either very old and did not yet support this particular feature, or claimed to support this feature but contained a bug.

In general, make sure to understand the limitations of the particular version of your particular compiler. For programs diagnosed as ill-formed as the example above, it is mostly a detective exercise such as the one following below, but using old compiler versions can have far worse consequences: compiler or C++ language defects that have only been addressed in later versions of the compiler.

See details below.


What particular C++17 feature is "the culprit"?

using std::integral_constant<std::size_t, I>::operator()...;

This is a pack expansion in a using-declaration, which was included in C++17 as:

  • P0195R2: Pack expansions in using-declarations

C++17 standards support in various compilers


GCC

// gcc 6.4: <source>:10:60: error: parameter packs not expanded with '...'
// gcc 7.1: OK

From C++ Standards Support in GCC - C++17 Support in GCC:

  • P0195R2 was implemented for GCC 7.

Thus, it is expected that your program will not compile for GCC 6.4, as feature was not yet implemented in that GCC version.


Clang

// clang 3.9.1: <source>:10:11: error: using declaration contains unexpanded parameter pack 'I'
// clang 4.0.0: OK

From C++ Support in Clang - C++17 implementation status:

  • P0195R2 was implemented for Clang 4.

Thus, as above, we cannot expect your program to compile for Clang < 4.


MSVC

// msvc 19.22: <source>(10): error C3520: 'I': parameter pack must be expanded in this context
// msvc 19.23: OK

From Microsoft C/C++ language conformance by Visual Studio version:

  • P0195R2 was claimed to have been (fully) implemented for VS 2017 15.7.

However the failure of MSVC 19.22 to compile your program is a bug:

Flagged to have been fixed in VS16.3/MSVC 19.23

dfrib
  • 70,367
  • 12
  • 127
  • 192