指针非类型模板参数在MSVC编译通过但GCC、Clang不通过的合规性问询
非类型模板参数指针实参的合法性判定
结论:GCC和Clang的行为符合C++标准,MSVC是通过编译器扩展支持了非标准写法
标准规则依据
C标准(涵盖C11至C++23各版本)明确规定,当非类型模板参数的类型为指针(或成员指针)时,对应的实参必须满足以下条件之一:
- 是空指针常量(如
nullptr、字面量0); - 指向具有静态存储期的对象或函数的指针;
- 指向类成员的指针;
- 空指针值。
你代码中的(int*)2是将整数2强制转换为int*类型,这个指针并未指向任何合法的、具有静态存储期的对象或函数,也不属于空指针常量范畴,完全不符合标准要求。
代码分析
你的代码片段:
template<typename T, T*> struct S{}; int main() { S<int, (int*)2> s4; // MSVC编译通过,GCC/Clang拒绝 }
MSVC允许该写法是因为它提供了非标准扩展,支持将任意整数转换后的指针作为非类型模板参数,但这不属于C++标准规定的合法用法。GCC和Clang严格遵循标准,因此拒绝编译这段代码。
内容的提问来源于stack exchange,提问作者user20562802
相关产品推荐
相关产品推荐

