【问题标题】:Is pointer type a literal type?指针类型是文字类型吗?
【发布时间】:2018-05-22 11:20:34
【问题描述】:

标量类型定义为

标识 T 是否为标量类型的特征类。标量类型 是一种具有加法运算符的内置功能的类型 没有重载(算术、指针、成员指针、枚举和 std::nullptr_t)。

它从integral_constant 继承为true_type 或 false_type,取决于 T 是否为标量类型,无论其 const 和/或 volative 限定条件。

表示指针是标量类型。

现在如果我们去定义字面量类型:

一个类型是文字类型,如果它是:

  • 标量类型;或
  • 引用类型;或
  • 文字类型的数组;要么 - 具有以下所有属性的类类型(第 9 条):
    • 它有一个微不足道的析构函数,
    • 每个构造函数调用和非静态数据成员(如果有)的大括号或等号初始化器中的完整表达式都是常量表达式 (5.19),
    • 它是一种聚合类型 (8.5.1) 或至少有一个不是复制或移动构造函数的 constexpr 构造函数或构造函数模板,并且
    • 它的所有非静态数据成员和基类都是文字类型。

现在,结合上面2个语句,它意味着指针是文字类型。但是指针不能是 constexpr。有人可以澄清一下吗?

进一步参见以下代码:

int a = 7;
constexpr int *pointer1 = &a;
int main ()
{
  int b = 4;
  constexpr int *pointer2 = &b;
}

pointer1 很好,但指针 2 出错。这是否意味着指向全局的指针很好,但指向自动变量不是?标准是否在任何地方提到这一点?

【问题讨论】:

  • "但是指针不能是 constexpr。" -- 你确定吗?
  • 看看SO: constexpr initializing with pointers。没有更深入的知识,但我的答案是指针可以constexpr.
  • 请不要以使现有答案无效的方式更改您的问题。就目前而言,这两个答案似乎只是重复了您在问题中添加的内容,即使他们回答了您最初提出的问题。
  • 对此感到抱歉..无法添加代码作为答案的注释..
  • 我在修改问题时得到了答案

标签: c++


【解决方案1】:

指针是文字类型。在某些条件下,它们可以是constexpr

[expr.const] 6

... [a pointer is constexpr if] 它包含具有静态存储持续时间的对象的地址、超过此类对象末尾的地址 (5.7)、函数的地址或空指针价值。

(其中“具有静态存储期限的对象”表示全局或静态对象,或此类对象的子对象。)

A demo:

int x;

int main()
{
    constexpr int *ptr = &x; // Compiles.

    // Doesn't compile: `error: '& foo' is not a constant expression`
    // int foo;
    // constexpr int *bar = &foo;
}

显然 GCC(使用 -pedantic-errors -std=c++11/14/17)很乐意接受超出范围的 constexpr 指针算法:constexpr int *ptr = &x - 10;,这对我来说似乎是一个错误。

【讨论】:

  • 我明白你的意思,但这并不完全正确。在int x; constexpr int *p = &x + 1; 中,p 不为空,也不指向全局或静态对象。
  • @hvd 点数。现在好点了吗?
  • 是的,这样会更好,但通常需要注意的是,未定义的行为会使表达式变为非常量,因此 int x; constexpr int *p = &x + 2; 是不行的。为了完整起见,当您处理指向函数的类型时,它们还可以指向函数。
  • 也许“超过此类对象末尾的地址”适用于两端。无论如何,这很可能是草稿中的一句话,即“不完整和不正确”
  • @Swift-FridayPie 我假设 “地址超过此类对象的末尾” 的意思是“刚好超过实际末尾的一个字节(不是开始)”。并且引用至少从 C++14 开始就存在并且没有太大变化......
【解决方案2】:

是的,它们是文字;是的,它们可以是 constexpr。演示:

constexpr int* foo=0;

int x = 7;

constexpr int* ptr=&x;

int main(){}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-14
    • 2015-04-06
    • 1970-01-01
    • 2018-05-30
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多