【问题标题】:noexcept specifier with default arguments construction具有默认参数构造的 noexcept 说明符
【发布时间】:2018-10-20 18:00:21
【问题描述】:

以下面的示例代码为例:

void test(const Item& item = Item()) {
   ...
}

假设一旦item 被传递给函数,this 就不能抛出。

问题是:函数应该标注noexcept还是noexcept(noexcept(Item()))

IHMO,前者应该没问题,但我不确定。非常感谢标准的引用!

【问题讨论】:

    标签: c++ language-lawyer noexcept


    【解决方案1】:

    默认参数是函数调用者的快捷符号。所以,当函数执行时,构造就已经完成了。

    因此,noexcept 应该足够了。

    standard [dcl.fct.default] 状态下:

    如果在参数声明中指定了初始化子句,则 初始化子句用作默认参数。默认参数将在缺少尾随参数的调用中使用。

    示例: 宣言 void point(int = 3, int = 4); 声明一个可以用零个、一个或两个 int 类型的参数调用的函数。它可以被调用 这些方式中的任何一种: point(1,2);point(1);point(); 最后两个调用相当于 point(1,4)point(3,4) 分别。

    还有一个注释(在[intro.execution]程序执行中):

    评估默认参数(8.3.6)涉及的子表达式是 被认为是在调用函数的表达式中创建的,而不是定义默认值的表达式 论据

    【讨论】:

    • 这正是我的想法。你能找到一些东西(即使来自 cppreference 也可以)来证明这一点?我的疑虑与 noexcept 转发有关:如果此函数为 noexcept,则 noexcept(test) 为真,但从调用者的角度来看会产生误导。
    • @dodomorandi 从语言来看,调用者已经创建了参数。 noexcept 说明符仅适用于函数本身。因此,构造可能抛出的问题与函数本身无关。
    • 那条笔记从最新的草稿中消失了:(
    • 我接受了你的回答,因为你完美地回答了我的问题。但是,我正在编辑这个问题,因为我想到了一个案例,如果您愿意,我希望您发表评论。
    • 这是正确的,但我要指出 Herb Sutter 曾经强烈建议不要使用类似的情况(传递一个其复制 c'tor 可能抛出的类型 - 按值),因为它很容易误导呼叫者,正如 dodomorandi 指出的那样。另一方面,noexcept(Item()) 比已构造参数时的要求更严格。这可能是“默认参数被认为有害”的另一种情况,我建议改用两个重载。
    猜你喜欢
    • 1970-01-01
    • 2020-05-08
    • 1970-01-01
    • 2017-09-27
    • 2017-06-30
    • 2015-01-28
    • 1970-01-01
    • 2016-01-06
    • 1970-01-01
    相关资源
    最近更新 更多