问题描述
查看 the 关于非类型模板参数的帖子,我对该帖子中的示例感到困惑,在此引用示例:
After looking at the post about non-type template argument,I have a confusion for an example in that post,I cite the example here:
struct VariableLengthString {
const char *data_ = nullptr;
constexpr VariableLengthString(const char *p) : data_(p) {}
auto operator<=>(const VariableLengthString&) const = default;
};
template<VariableLengthString S>
int bar() {
static int i = 0;
return ++i;
}
int main() {
int x = bar<"hello">(); // ERROR
}
帖子说相关的措辞是[temp.arg.nontype]/2",所以我看了一下这个规则,它限制了什么可以是非类型模板参数.
The post says "the relevant wording is [temp.arg.nontype]/2",So I took a look at that rule,It constrains what can be a non-type template argument.
所以,我看了一下转换后的常量表达式
,它的定义在这里:
So,I took a look at converted constant expression
,Its definitions are here:
什么是常量表达式?这些规则在这里:
What is a constant expression?These rules are here:
那么,类类型 VariableLengthString
是文字类吗?是的,可以在这里证明哪些规则:
So,Is the class type VariableLengthString
a literal class?Yes,it is.what rules can prove that are here:
- 它有一个琐碎的析构函数
- 它是闭包类型,聚合类型,或者至少具有一个constexpr构造函数或构造函数模板(可能从基类继承),而不是复制或移动构造函数,
- 如果不是联合,则其所有非静态数据成员和基类均为非易失性文字类型.
关键是,这些类型为 VariableLengthString
的对象的子对象类型是否都是文字类型?类 VariableLengthString
是否至少有一个constexpr构造函数?是的.因为这些规则:
The key point is that,Are these types of sub-objects of ojbects of type VariableLengthString
all literal types? Does the class VariableLengthString
have at least one constexpr constructor?Yes they are.Because of these rules:
因此,子对象 data _
是指针类型.因此,它是标量类型,也是文字类型.满足项目符号3.是否 constexpr VariableLengthString(const char *p)
一个constexpr构造函数?是的,因为这些规则:
So,the sub-object data_
,it's of type pointer.hence,it's scalar type,also a literal type.The bullet 3 is satisfied.Does constexpr VariableLengthString(const char *p)
a constexpr constructor?Yes,it is,Because of these rules:
- 该类不应具有任何虚拟基类;
- 每种参数类型应为文字类型;
- 每个不变的非静态数据成员和基类子对象都应初始化
对于 constexpr VariableLengthString(const char * p)
,这三个规则都得到满足.总之, VariableLengthString
类是一个文字类型和constexpr表达式类型 VariableLengthString
可以用作非类型模板参数,因为它满足转换后的常量表达式的要求.为什么上面的代码格式错误?错过了一些,请帮助我找出它们.
For constexpr VariableLengthString(const char *p)
,these three rules are all be satisfied.In summary,the class VariableLengthString
is a literal type and a constexpr expression of type VariableLengthString
could be used as a non-type template argument,because it satisfies the requirement of being a converted constant expression.why the code above is ill-formed?If I miss something,please help me find out them.
推荐答案
该代码格式错误,因为标准是这样的:
The code is ill-formed because the standard says so:
...
- 字符串文字
已添加重点.C ++ 17和更低版本不允许您将指向文字的指针用作NTTP.因此,C ++ 20不允许您通过NTTP的类成员 smuggle 指向文字的指针.
Emphasis added. C++17 and before would not allow you to use a pointer to a literal as an NTTP. C++20 therefore doesn't allow you to smuggle a pointer to a literal through a class member of an NTTP.
这篇关于为什么带有指针子对象的文字类类型的constexpr表达式不能是非类型模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!