lambda捕获什么都不能访问全局变量?

时间:2017-05-07 03:54:48

标签: c++ c++11 lambda global-variables standards

int n;    
int main()
{
    [](){ n = 0; }(); // clang says "ok"

    int m;
    [](){ m = 0; }(); // clang says "not ok"
}

我只是想知道:

如果lambda没有捕获任何内容,是否允许按照C ++标准访问全局变量?

2 个答案:

答案 0 :(得分:17)

是的,当然。正常的名称查找规则适用。

  

[expr.prim.lambda] / 7 ...出于名称查找的目的... 复合语句λ-表达

Re:为什么局部变量的处理方式与全局变量不同。

  

[expr.prim.lambda] / 13 ...如果一个 lambda-expression 或一个普通lambda odr使用的函数调用操作员模板的实例化(3.2)<android.support.v7.widget.RecyclerView xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:scrollbars="horizontal" app:layoutManager="android.support.v7.widget.LinearLayoutManager"/> 或从其到达范围具有自动存储持续时间的变量,该实体应由 lambda-expression 捕获。

     

[expr.prim.lambda] / 9 lambda-expression 其最小的封闭范围是块范围(3.3.3)是本地lambda表达式 ...本地lambda表达式的到达范围是一组封闭范围,包括最里面的封闭函数及其参数。

在您的示例中,View rootView = inflater.inflate(R.layout.discover_fragment, container, false); LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false); recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView); recyclerView.setLayoutManager(layoutManager); 是一个变量,具有自lambda到达范围的自动存储持续时间,因此应被捕获。 View rootView = inflater.inflate(R.layout.discover_fragment, container, false); LinearLayoutManager layoutManager = new GridLayoutManager(getActivity(), 1, GridLayoutManager.HORIZONTAL, false); recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView); recyclerView.setLayoutManager(layoutManager); 不是,所以不一定。

答案 1 :(得分:3)

默认情况下访问全局,静态和const变量:

#include <iostream>

int n;    
int main()
{
    [](){ n = 10; }();
    std::cout << n << std::endl;
    static int m = 1;
    [](){ m = 100; }();
    std::cout << m << std::endl;
    const int l = 200;
    [](){ std::cout << l << std::endl; }();
}