GCC 4.7.2编译:
constexpr int i = 5;
[]{ std::integral_constant< int, i >(); }; // nonstandard: i not captured
Run Code Online (Sandbox Code Playgroud)
但不是这个:
constexpr int i = 5;
[&i]{ std::integral_constant< int, i >(); }; // GCC says i not constexpr
Run Code Online (Sandbox Code Playgroud)
根据C++11§5.1.2/ 15,后一个例子对我来说是正确的:
如果实体是隐式或显式捕获但未通过复制捕获,则通过引用捕获实体.未指定是否在闭包类型中为通过引用捕获的实体声明了其他未命名的非静态数据成员.
似乎ilambda中捕获的对象引用了封闭范围中的变量constexpr,而不仅仅是const引用.
该标准明确指出,使用按值捕获转换为对lambda对象的相应成员的使用.我认为5.1.2提示我的解释是正确的.
是否有任何明确说明通过引用捕获是否引用封闭范围中的对象或引用?
我想在lambda中使用constexpr值.阅读使用lambda捕获的constexpr值作为数组维度的答案 ,我假设以下应该工作:
#include<array>
int main()
{
constexpr int i = 0;
auto f = []{
std::array<int, i> a;
};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然而,Clang 3.8(std = c ++ 14)抱怨说
变量'i'不能在没有指定capture-default的lambda中隐式捕获
这应该被视为clang 3.8中的错误吗?
BTW:
上面的代码用gcc 4.9.2编译.如果我将lambda表达式更改为显式捕获:
...
auto f = [i]{
...
Run Code Online (Sandbox Code Playgroud)
clang 3.8编译它,但gcc 4.9.2失败:
错误:'i'的值在常量表达式中不可用...
我在使用lambdas时遇到了一个有趣的案例(至少对我来说),并且想知道它是编译器错误还是标准功能允许的东西.
让我们切入追逐.有示例代码:
const int controlValue = 5;
std::vector<int> vect{ 0, 1, 2, 3 };
const auto result = std::any_of(vect.begin(), vect.end(), [](const int& item)
{
return item == controlValue;
});
Run Code Online (Sandbox Code Playgroud)
请注意,controlValuelambda表达式不捕获变量.另外,在lambda表达式的cppreference中说明了这一点[] - captures nothing
使用VS2015编译上面的代码会产生一个错误,这并不奇怪:
error C3493: 'controlValue' cannot be implicitly captured because no default capture mode has been specified
Run Code Online (Sandbox Code Playgroud)
但是,当使用MinGW与gcc 4.8.2相同的例子编译和工作.一些在线编译器包括gcc 5.4.0,clang 3.8.0给出了类似的结果.
当controlValue失去它const然后所有测试的编译器给出所有期望的错误(没有捕获变量,这是好的).
在这种情况下,哪些编译器符合标准?这是否意味着某些优化或其他"黑客"在这里用于const变量?也许某些内容是隐含的?谁能解释一下这里发生的情况?
编辑:
有人指出这个问题是Lambda捕获constexpr对象 的重复.虽然答案可能有些相关(指向odr用例),但是有关在通过ref捕获时发生错误的问题.这里的主题是完全不同的,并且侧重于根本不捕获显式变量(尽管在lambda体中使用它).
在查看了更多与lambda相关的问题之后,如果有人感兴趣,我会指出使用lambda捕获的constexpr值作为数组维度 …