在using声明中引用但未扩展的参数包:编译器错误与否?



考虑以下代码(也可以在编译器资源管理器中找到)

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

对于许多编译器,它会导致编译错误:

// 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

对我来说,这似乎是完全有效的c++17代码,但我很惊讶,它似乎不编译相对较新的编译器(特别是intelmsvc)(即使它编译在所有最新的版本)。

我想知道是否:

  • 这是完全c++17有效的代码,它只是花了很长时间为一些供应商实现它
  • 不是纯c++17有效代码

我想知道是否:

  • 它完全是c++17的有效代码,只是一些供应商花了很长时间来实现它
  • 它不是纯粹的c++17有效代码

代码是有效的,但是你列出的编译器版本要么很旧,还不支持这个特定的特性,要么声称支持这个特性,但包含一个错误。

一般来说,一定要了解特定编译器的特定版本的限制。对于像上面的例子那样被诊断为格式不良的程序,主要是像下面这样的检测练习,但是使用旧的编译器版本可能会有更糟糕的后果:编译器或c++语言缺陷,这些缺陷只有在以后的编译器版本中才能解决。

详情见下文


c++ 17的哪个特性是"罪魁祸首"?

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

这是using声明中的包扩展,在c++ 17中包含为:

  • P0195R2: using-declarations
  • 中的包扩展

各种编译器对c++ 17标准的支持

GCC

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

从GCC中的c++标准支持到GCC中的c++ 17支持:

  • P0195R2为GCC 7实现。

因此,预计您的程序将无法在GCC 6.4中编译,因为该特性尚未在该GCC版本中实现。


叮当声

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

来自Clang中的c++支持- c++ 17实现状态:

  • P0195R2在Clang 4中实现。

因此,如上所述,我们不能期望您的程序能够为Clang <4 .


MSVC

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

来自Microsoft C/c++语言一致性的Visual Studio版本:

  • P0195R2据称已在VS 2017 15.7中(完全)实现。

但是MSVC 19.22无法编译你的程序是一个bug:

  • 可变模板:无效的参数包上下文

在VS16.3/MSVC 19.23中被标记为已修复

相关内容

最新更新