未捕获 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
;那是您命名了一个成员(这是x
的odr-use)。这是相同的问题和错误。 x
在您的任何一个示例中都不是 int
。
好的,现在我在中间添加了第二个 sn-p。我不明白为什么第一个失败而第二个还可以
【参考方案1】:
当您在第一个示例中 return x;
时,您必须调用 A
的复制构造函数,这涉及将 reference 绑定到 x
并因此 odr 使用它。可以说,可用于常量表达式的值的简单副本不应构成 odr-use 任何超过 return x.a;
,但该规则中没有这样的例外,因此 Clang 是正确 拒绝它。
实际上,您当然可以使任何constexpr
变量static
以避免任何需要捕获它。
【讨论】:
这是有道理的。谢谢以上是关于未捕获 constexpr 变量的主要内容,如果未能解决你的问题,请参考以下文章
使用 lambda 捕获的 constexpr 值作为数组维度
使用 constexpr 成员函数初始化 constexpr 成员变量
constexpr 具有未触及的非 constexpr 参数:谁是正确的,clang 还是 gcc?