【问题标题】:constexpr variable not captured未捕获 constexpr 变量
【发布时间】:2021-03-21 09:01:39
【问题描述】:

以下代码在 clang 中无法编译(在 GCC 中可以):

struct A{
    int a;
};

auto test(){
    constexpr A x{10};
    return []{
        return x; // <-- here x is A: clang doesn't compile
    }();
}

Clang 的错误是 在未指定捕获默认值的 lambda 中无法隐式捕获变量“x”,但我认为始终捕获 constexpr 变量。

如果 x 是 int,则代码编译:

auto test(){
    constexpr int x{10};
    return []{
        return x; // <-- here x is int: clang is ok
    }();
}

有趣的是,下面的代码也可以编译:

auto test(){
    constexpr A x{10};
    return []{
        return x.a;
    }();
}

叮当声对吗?如果是这样,理由是什么? 我正在使用 -std=c++17

--编辑--

以下问题: Can I use a constexpr value in a lambda without capturing it? 与这个无关,因为与 clang11 一样,它不再是一个问题:事实上,如上所述,如果 x 是一个 int,clang11 编译。

https://godbolt.org/z/rxcYjz 中也有示例代码

【问题讨论】:

  • 确保在 C++ 问题中添加 c++ 标签,以便更多用户看到帖子。
  • “以下问题:我可以在 lambda 中使用 constexpr 值而不捕获它吗?与这个无关,因为与 clang11 一样,它不再是一个问题:事实上,作为如上所述,如果 x 是 int,则 clang11 编译。” 字面意思是一样的。
  • @AsteroidsWithWings,不同之处在于在那个问题中甚至不可能使用 int。现在一个 int 是可以的,任何其他对象都不是。还是clang的问题吗?
  • @MarioDemontis 不是你用过int;那是您命名了一个成员(这是xodr-use)。这是相同的问题和错误。 x 在您的任何一个示例中都不是 int
  • 好的,现在我在中间添加了第二个 sn-p。我不明白为什么第一个失败而第二个还可以

标签: c++ lambda c++17 constexpr clang++


【解决方案1】:

当您在第一个示例中 return x; 时,您必须调用 A 的复制构造函数,这涉及将 reference 绑定到 x 并因此 odr 使用它。可以说,可用于常量表达式的值的简单副本不应构成 odr-use 任何超过 return x.a;,但该规则中没有这样的例外,因此 Clang 是正确 拒绝它。

实际上,您当然可以使任何constexpr 变量static 以避免任何需要捕获它。

【讨论】:

  • 这是有道理的。谢谢
猜你喜欢
  • 2019-08-03
  • 2015-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
相关资源
最近更新 更多