【问题标题】:Why does C++17 if statement with initializer not work as expected?为什么带有初始化程序的 C++17 if 语句不能按预期工作?
【发布时间】:2021-07-28 18:19:16
【问题描述】:
struct A
{
    auto g1()
    {
        return true;
    }

    void f()
    {
        if (auto b = g1(); b) // ok
        {
            return;
        }

        if (auto b = g2(); b) // error: use of 'auto A::g2()' before deduction of 'auto'
        {
            return;
        }
    }    
    
    auto g2()
    {
        return true;
    }
};

为什么带有初始化程序的 C++17 if 语句不能按预期工作?

【问题讨论】:

  • 您可以将您的演示简化为struct A { void f() { g2(); } auto g2() { } };。 if-initializer 是一个红鲱鱼。
  • 我在这里猜测,但这是否与我们可以在类中调用稍后声明的函数的原因相同?在检查类本身之后检查成员函数的主体。正因为如此,auto 推导还没有开始,因为函数体还没有被解析。如果你把g2 放在f 上面,它就可以正常工作。
  • @OP,我注意到你用标准标签标记了这个。这是否意味着您正在寻找标准中的文本来支持发布的任何答案?
  • @NathanOliver,是的。这正是我的意思。
  • 好的。我更新为使用语言律师标签

标签: c++ c++17 language-lawyer auto type-deduction


【解决方案1】:

因为标准是这样说的(引自最新草案):

[dcl.spec.auto.general]

如果命名了具有未推导占位符类型的变量或函数 通过表达式 ([basic.def.odr]),程序是非良构的。一旦 但是,在函数中看到了未丢弃的 return 语句, 从该语句推导出的返回类型可用于其余的 函数,包括在其他返回语句中。

[示例 4:

auto n = n;                     // error: n's initializer refers to n
auto f();
void g() { &f; }                // error: f's return type is unknown

为了澄清一点,g2 的“声明”是“可见的”,因为g1 的定义在完整类上下文中。但这并没有扩展到看到g2 的定义。

【讨论】:

    猜你喜欢
    • 2019-05-30
    • 1970-01-01
    • 2013-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 1970-01-01
    • 2017-06-18
    相关资源
    最近更新 更多