![](/img/trans.png)
[英]Why does C++11's lambda require "mutable" keyword for capture-by-value, by default?
[英]Does C++11 require this lambda to be declared mutable?
考虑一下这个C ++ 11代码:
#include <functional>
#include <cstdlib>
template <typename F>
void test(F &&f) {
auto foo = [f]() {
f();
};
foo();
}
int main() {
test(std::bind(std::puts, "hello"));
return 0;
}
GCC和Clang接受此作为有效的C ++ 11代码,但Visual Studio 2013要求将lambda声明为可变( auto foo = [f]() mutable { ... }
)。 否则我收到此错误:
错误C3848:类型为'
const std::_Bind<true,int,int (__cdecl *const )(const char *),const char (&)[6]>
cdeclconst std::_Bind<true,int,int (__cdecl *const )(const char *),const char (&)[6]>
'的表达式会丢失一些const-volatile限定符以便调用'int std::_Bind<true,int,int (__cdecl *const )(const char *),const char (&)[6]>::operator ()<>(void)
'
Visual Studio是否正确拒绝此代码而没有可变,或者它是否有效C ++ 11?
(好奇Clang拒绝代码,如果你将std::bind(std::puts, "hello")
改为std::bind(std::exit, 0)
显然是因为它认为noreturn
使函数类型不同;我'我很确定这是一个错误。)
这不是关于lambdas的。
#include <functional>
#include <cstdlib>
int main() {
const auto x = std::bind(std::puts, "hello");
x();
}
这被GCC接受,但被MSVC拒绝。
IMO是否有此标准尚不清楚。 std::bind
的返回值g
有一个未指定的返回类型, g(...)
有效并根据g
的cv限定符定义,但标准实际上并没有说任何operator()
必须可以为const
限定的对象或引用调用。 它强烈暗示这是有效的,因为否则对g
的cv-qualifiers的引用似乎没用,但它实际上并不认为它是有效的。
因此,我认为MSVC的行为不是标准作者的意图,但它可能符合标准的要求。
这看起来像在Visual Studio实现的一个bug bind
,只有非const函数调用操作符返回一个类型。 它应该返回一个类型,它将所有函数调用转发给绑定的函数对象,而不管它自己的cv资格。
总结C ++ 11 20.8.9.1.2中相当不透明的语言,对bind
结果的函数调用应该转发给绑定的函数对象,因此如果允许对该对象进行调用则应该允许。 因此,如果const
函数对象不可调用,那将是一个错误; 但在这里,作为一个函数指针,无论cv资格如何,它都是可调用的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.