【问题标题】:C++14: can you call new in a constexpr?C++14:你可以在 constexpr 中调用 new 吗?
【发布时间】:2014-02-20 02:41:23
【问题描述】:

当 C++14 取消对 constexpr 的限制时,它似乎包括以下内容(复制自 Wikipedia):

表达式可能会改变对象的值,如果该对象的生命周期 对象开始于常量表达式函数内。这包括 调用任何非 const constexpr 声明的非静态成员函数。

这似乎意味着您可以使用new 创建一个对象,并且只要您在表达式中delete 它就可以了。

【问题讨论】:

    标签: c++ c++11 language-lawyer c++14


    【解决方案1】:

    语言律师回答。所有对N3797的引用。

    7.1.5/5 状态:

    对于非模板、非默认 constexpr 函数或非模板、非默认、非继承 constexpr 构造函数,如果不存在参数值,则函数或构造函数的调用可以核心常量表达式 (5.19) 的求值子表达式,程序格式错误;无需诊断。

    跳到 5.19,我们看到:

    一个条件表达式 e 是一个核心常量表达式 除非e 的评估,遵循抽象机(1.9)的规则,将评估以下表达式之一:

    • ...[很多子弹]...

    • 一个新表达式 (5.3.4);

    • 一个删除表达式 (5.3.5);

    • ...[更多子弹]...

    所以不:包含constexpr 函数且其中无条件调用newdelete 的程序是格式错误的,不需要诊断。 (但是,如果任何半体面的编译器未能在 constexpr 函数中诊断出此类对 newdelete 的调用,我会感到惊讶,无论是否需要。)

    【讨论】:

    • 但是,如果任何半体面的编译器无法诊断 constexpr 函数中的 new 或 delete 实例,无论是否需要,我都会感到惊讶。 这不是问题在 constexpr 函数中有 newdelete。例如,这个是完全合法的(虽然很傻)constexpr int f(int a) { return a ? a : *new int(0); } 只要用非零整数调用,我们就可以了。对于所有函数参数将评估new的情况,不需要诊断,并且代码格式错误。
    • 2018 年更新:clang 和 gcc 仍然默默地接受错误代码....
    【解决方案2】:

    我不这么认为。您仍然只能调用其他 constexpr 函数。 new 实际上是对operator new() 的函数调用,它不是constexpr 函数。 delete 也是如此。

    【讨论】:

    • 调用operator new() 是使用new 运算符的几个效果之一。 (另一个重要的作用是运行对象构造函数)。同上delete,它在释放函数之前调用析构函数。
    猜你喜欢
    • 1970-01-01
    • 2013-12-24
    • 2015-08-26
    • 2020-08-28
    • 1970-01-01
    • 1970-01-01
    • 2014-03-14
    • 2017-01-15
    • 2020-08-26
    相关资源
    最近更新 更多