C++17允许constexpr成员指针作模板实参的原因解析
问题解析:C11与C17模板实参的差异
已知C17引入了template<auto>特性,但下述示例未使用该特性,却仅能在C17环境下编译通过:
struct Foo { int bar; }; template<int Foo::*> void takePtrToMember() {} int main() { takePtrToMember<&Foo::bar>(); // 此写法在所有版本均生效 constexpr auto x = &Foo::bar; takePtrToMember<x>(); // 此写法仅在C++17生效 return 0; }
为什么无法在C++11中运行?
在C++11的规则里,针对指向成员指针这类非类型模板参数,允许的实参范围非常严格:只能是&类名::成员名这类直接表达式、空指针常量,或者同类型的模板参数。
虽然x是constexpr变量,值完全符合要求,但它属于命名的常量表达式,不在C++11允许的非类型模板实参范畴内,因此编译器会拒绝这种写法。
C++17做出了哪些改动使其被允许?
C++17大幅放宽了非类型模板实参的限制:只要某个表达式是符合模板参数类型要求的常量表达式,不管是直接书写的字面形式,还是命名的constexpr变量,都可以作为实参传递。
回到这个例子,constexpr变量x是类型为int Foo::*的常量表达式,完全匹配模板参数的类型,因此在C++17中被允许作为模板实参使用。
内容的提问来源于stack exchange,提问作者dragonroot
相关产品推荐
相关产品推荐

