本文介绍了为什么带有指针子对象的文字类类型的constexpr表达式不能是非类型模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

查看 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:

  1. 它有一个琐碎的析构函数
  2. 它是闭包类型,聚合类型,或者至少具有一个constexpr构造函数或构造函数模板(可能从基类继承),而不是复制或移动构造函数,
  3. 如果不是联合,则其所有非静态数据成员和基类均为非易失性文字类型.

关键是,这些类型为 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:

  1. 该类不应具有任何虚拟基类;
  2. 每种参数类型应为文字类型;
  3. 每个不变的非静态数据成员和基类子对象都应初始化

对于 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表达式不能是非类型模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 10:07