是否有可能在lambda表达式中通过const引用捕获?

我希望下面标记的作业失败,例如:

#include <algorithm>
#include <string>

using namespace std;

int main()
{
    string strings[] = 
    {
        "hello",
        "world"
    };
    static const size_t num_strings = sizeof(strings)/sizeof(strings[0]);

    string best_string = "foo";

    for_each( &strings[0], &strings[num_strings], [&best_string](const string& s)
      {
        best_string = s; // this should fail
      }
    );
return 0;
}

更新:由于这是一个老问题,如果c++ 14中有帮助解决这个问题的工具,更新它可能会很好。c++ 14中的扩展允许我们通过const引用捕获非const对象吗?(2015年8月)


当前回答

使用clang或等待,直到这个gcc错误被修复: bug 70385:通过const引用捕获Lambda失败[https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70385]

其他回答

使用const只会让算法的&号将字符串设置为它的原始值, 换句话说,lambda不会真正将自己定义为函数的参数,尽管周围的作用域将有一个额外的变量…… 如果没有定义它,它不会将字符串定义为典型的 [&, &best_string](字符串常量) 因此,如果我们仅仅停留在那里,尝试捕获引用,很可能会更好。

在c++14中使用static_cast / const_cast:

[&best_string = static_cast<const std::string&>(best_string)](const string& s)
{
    best_string = s; // fails
};

DEMO


在c++17中使用std::as_const:

[&best_string = std::as_const(best_string)](const string& s)
{
    best_string = s; // fails
};

演示2

使用clang或等待,直到这个gcc错误被修复: bug 70385:通过const引用捕获Lambda失败[https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70385]

从n3092开始,Const不在捕获语法中:

capture:
  identifier
  & identifier
  this

文本只提到了复制捕获和引用捕获,没有提到任何形式的const-ness。

对我来说,这是一个疏忽,但我没有非常密切地遵循标准化过程。

我想如果你不使用变量作为函子的参数,那么你应该使用当前函数的访问级别。如果你认为不应该,那么把和这个函数分开,它不是函数的一部分。

不管怎样,你可以通过使用另一个const引用来轻松实现你想要的东西:

#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    string strings[] = 
    {
        "hello",
        "world"
    };
    static const size_t num_strings = sizeof(strings)/sizeof(strings[0]);

    string best_string = "foo";
    const string& string_processed = best_string;

    for_each( &strings[0], &strings[num_strings], [&string_processed]  (const string& s)  -> void 
    {
        string_processed = s;    // this should fail
    }
    );
    return 0;
}

但这和假设你的必须与当前函数隔离是一样的,使它成为非。