ISO C++ 11规范的第5.1.2节第10节规定:
使用通常的非限定名称查找规则(3.4.1)查找捕获列表中的标识符; 每个这样的查找应该找到一个变量,其自动存储持续时间在本地lambda表达式的到达范围内声明.如果实体(即变量或此实体)出现在lambda表达式的捕获列表中,则称其被明确捕获.
这似乎意味着lambda无法捕获文件范围变量.例如,该程序应该是非法的:
#include <iostream>
int x = 13;
int main()
{
  auto l = [](){ return x; };
  std::cout << l() << std::endl;
  return 0;
}
但是,g++4.7.1会产生我期望的结果:
$ g++ --version
g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ -std=c++11 lambda.cpp 
$ ./a.out 
13
但clang …
我试图优雅地声明一个常量std::set对象,它将是另外两个常量std::set对象的合并。
#include <set>
const std::set<int> set_one = { 1,2,3 };
const std::set<int> set_two = { 11,15 };
const std::set<int> set_all = { 1,2,3,11,15 }; // this is not very elegant, duplication
以set_all这种方式声明对象不太优雅,因为它复制了前两行的信息。有没有办法在声明中使用set_one和set_two常量set_all?
像这样的东西:
const std::set<int> set_all = set_one + set_two; // this does not compile, of course!
#include <set>
#define SET_ONE 1, 2, 3
#define SET_TWO 11, 15
const std::set<int> set_one = { SET_ONE …下面两个 lambda 函数哪一个是正确的?
#include <cstdlib>
extern constinit int exit_code { };
int main( )
{
    auto lambda_1 { [ &exit_code ]( ) noexcept
                    {
                        exit_code = EXIT_FAILURE;
                    } };
    auto lambda_2 { [ ]( ) noexcept
                    {
                        exit_code = EXIT_FAILURE;
                    } };
    lambda_1( );
    lambda_2( );
    return exit_code;
}
海湾合作委员会警告&exit_code:
#include <cstdlib>
extern constinit int exit_code { };
int main( )
{
    auto lambda_1 { [ &exit_code ]( ) noexcept
                    {
                        exit_code = EXIT_FAILURE;
                    } };
    auto lambda_2 …