Dus*_*teh 16 c++ lambda language-lawyer c++11
我在使用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值作为数组维度
(与@Barry说的相同)建议VS2015错误并显示controlValue在此示例中设置变量以static修复VS2015下的编译.
Bar*_*rry 16
这是一个VS错误.代码完美无缺.
[expr.prim.lambda]中的规则是:
如果lambda表达式或函数的实例化调用泛型lambda odr的操作符模板- 使用(3.2)此变量或具有自其存储持续时间的变量,则该实体应由lambda表达式捕获.
根据[basic.def.odr],如果变量是odr-used的话:
变量x的名称显示为潜在评估的表达式ex,除非将lvalue-to-rvalue转换(4.1)应用于x,否则会产生一个不调用任何非平凡函数的常量表达式(5.20).,如果x是一个对象,则ex是表达式e的潜在结果集的一个元素,其中左值到右值的转换(4.1)应用于e,或者e是丢弃值表达式(第5条) ).
并且,来自[expr.const]:
条件表达式e是核心常量表达式,除非根据抽象机器(1.9)的规则评估e将评估以下表达式之一:[...]左值到右值的转换(4.1)除非它应用于整数或枚举类型的非易失性glvalue,它引用具有前面初始化的完整非易失性const对象,用常量表达式初始化
在:
return item == controlValue;
Run Code Online (Sandbox Code Playgroud)
controlValue是一个整数类型的glvalue,它指的是用常量表达式初始化的完整的非易失性const对象.因此,当我们controlValue在涉及左值到右值转换的上下文中使用时,它不会被使用.由于它没有使用,我们不需要捕获它.
当您更改controlValue为不 - const,它不再是一个常量表达式,和平等检查ODR-使用它.由于它没有被捕获但是使用得很多,所以lambda是不正确的.
请注意,标准中出现了这样的示例:
void f(int, const int (&)[2] = {}) { } // #1
void f(const int&, const int (&)[1]) { } // #2
void test() {
const int x = 17;
auto g = [](auto a) {
f(x); // OK: calls #1, does not capture x
};
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1638 次 |
| 最近记录: |