【问题标题】:Does declaring a constexpr object marks the constructor as constexpr声明 constexpr 对象是否将构造函数标记为 constexpr
【发布时间】:2022-09-23 16:52:34
【问题描述】:

我只是在理解编译器将构造函数标记为 constexpr 时遇到了问题。

如果我编写以下程序:

struct S{ S() {}; }

constexpr S s{ };

这是否意味着默认构造函数被标记为 constexpr?

  • \"这是否意味着默认构造函数被标记为 constexpr?\"您明确将其定义为非 constexpr。
  • 哦,你的程序格式不正确!

标签: c++ constexpr default-constructor


【解决方案1】:

隐式定义的构造函数是编译器在遇到某些上下文时隐式定义的构造函数(见下文)。但是,显式定义的构造函数是由用户定义的构造函数,而不是由编译器定义的构造函数。

现在每个[class.default.ctor]/4

默认且未定义为已删除的默认构造函数是 在使用 odr ([basic.def.odr]) 创建一个 其类类型的对象([intro.object]),当需要它时 常量评估([expr.const]),或者当它被明确默认时 在其第一次声明之后。隐式定义的默认值 构造函数执行类的初始化集 将由用户编写的默认构造函数执行 没有 ctor-initializer 和空复合语句的类。如果 用户编写的默认构造函数格式不正确,程序 格式不正确。如果该用户编写的默认构造函数满足 constexpr 构造函数 ([dcl.constexpr]) 的要求, 隐式定义的默认构造函数是 constexpr [..]

本段只是告诉您,未删除的默认默认构造函数在被使用或需要用于常量评估或在其第一次声明后显式默认时是隐式定义的。

此外,它告诉您,隐式定义的构造函数与用户编写的默认构造函数相同,其主体为空且没有成员初始化器列表。

然后,如果其对应的用户编写的默认构造函数满足所有[dcl.constexpr]/3 条件,它会告诉您它被定义为constexpr

也就是说,如果满足[dcl.constexpr]/3 的所有要求,则隐式或显式默认构造函数将被隐式定义为constexpr。另一方面,无论是显式定义还是显式声明的构造函数都不会被隐式定义为 constexpr,即使它满足所有 [dcl.constexpr]/3 也是因为您显式定义了它们。但是如果你显式地将它标记为constexpr,它将是一个constexpr构造函数,同时它应该满足所有[dcl.constexpr]/3条件。

所以在你的例子中:

struct S{ S() {}; }
constexpr S s{ };

这是不正确的,因为 S 不是 literal type 并且您试图在常量表达式上下文中调用非 constexpr 构造函数,这在 [const.expr]/(5.2) 中是不允许的

【讨论】:

    【解决方案2】:

    如果整个构造函数本身是隐式声明的,或者在其第一个声明中默认为 = default,则构造函数仅(可能)是隐式 constexpr

    您正在手动声明构造函数并且您没有默认它,因此如果您将 constexpr 说明符添加到声明中,它只会是 constexpr

    因此显示的构造函数不是constexpr,因此constexpr S s{ }; 将无法编译,因为初始化将调用非constexpr 构造函数,这在常量表达式中是不允许的。但是,变量声明上的constexpr 确实要求变量的初始化(包括初始化程序的评估)是一个常量表达式。

    【讨论】:

    • 在最后一行(“要求初始化”), 你的意思“初始化器”代替“初始化”?
    • @JasonLiam 不,我打算包括对象本身的构造,而不仅仅是初始化程序中的表达式(如果有的话)。该标准使用短语“其初始化的完整表达式“虽然这可能不是完全明确的。
    • 我想知道如何“初始化可以是常量表达式”.
    • @JasonLiam 意图是整个初始化(意味着作为变量构造和初始化器评估的一部分的所有评估)在被视为表达式时是一个常量表达式。正如我所说,这目前似乎并没有得到很好的定义。你可以看到例如github.com/cplusplus/draft/issues/4852 对此进行讨论。
    猜你喜欢
    • 2023-03-25
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 1970-01-01
    • 1970-01-01
    • 2016-12-15
    相关资源
    最近更新 更多