未捕获 constexpr 变量

Posted

技术标签:

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

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

struct A
    int a;
;

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

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

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

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

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

auto test()
    constexpr A x10;
    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。我不明白为什么第一个失败而第二个还可以 【参考方案1】:

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

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

【讨论】:

这是有道理的。谢谢

以上是关于未捕获 constexpr 变量的主要内容,如果未能解决你的问题,请参考以下文章

使用 lambda 捕获的 constexpr 值作为数组维度

逗号运算符使lambda表达式非constexpr

使用 constexpr 成员函数初始化 constexpr 成员变量

constexpr 具有未触及的非 constexpr 参数:谁是正确的,clang 还是 gcc?

为啥我不能使用 constexpr 全局变量来初始化 constexpr 引用类型?

c++ 默认构造函数 constexpr 还是正确未定义?