含void类型局部参数的requires表达式:哪个编译器处理合规?
C++ requires-expression含void参数的标准合规性问题
C++的requires-expression可通过参数列表引入局部参数,若参数列表中存在类型为void的参数,该表达式是返回false还是触发编译错误?
示例1
template<typename T> concept C = requires(T t, void v) { t; }; static_assert(!C<int>);
- Clang和MSVC接受这段代码,且
static_assert(!C<int>)编译通过(即requires表达式返回false) - GCC报错:
error: invalid use of type 'void' in parameter declaration
示例2
static_assert( requires(int t, void) {t;} );
- Clang接受该代码,且requires表达式返回true,
static_assert编译通过 - GCC报与示例1相同的错误
- MSVC报错:
error C2860: 'void' cannot be used as a function parameter except for '(void)'
标准合规性分析
根据C++20标准([expr.requires]/8)的明确规定:requires-expression的参数声明子句中,每个参数声明的类型不能是cv-qualified的void。也就是说,无论参数是否有名称,只要参数类型为void(包括const/volatile修饰的void),这种写法都是格式错误,编译器应当触发编译错误。
因此,GCC的处理符合C++标准:它在两个示例中都正确识别到了违反标准的写法并报错。而Clang和MSVC的处理属于非标准扩展或实现偏差,不符合标准要求。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

