Sam*_*des 27 c++ lambda language-lawyer c++11 visual-studio-2013
考虑一下这个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;
}
Run Code Online (Sandbox Code Playgroud)
GCC和Clang接受此作为有效的C++ 11代码,但Visual Studio 2013要求将lambda声明为mutable(auto foo = [f]() mutable { ... }
).否则我收到此错误:
错误C3848:具有类型'
const 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
使函数类型不同;我很确定这是一个错误.)
小智 14
这不是关于lambdas的.
#include <functional>
#include <cstdlib>
int main() {
const auto x = std::bind(std::puts, "hello");
x();
}
Run Code Online (Sandbox Code Playgroud)
这被GCC接受,但被MSVC拒绝.
IMO是否有此标准尚不清楚.返回值g
的std::bind
都有一个未指定的返回类型为这g(...)
是有效的,在的cv修饰符来定义g
,但该标准实际上不说任何operator()
必须是可调用的const
-qualified对象或引用.它强烈暗示这是有效的,因为否则对g
cv-qualifiers 的引用似乎没用,但它实际上并不认为它是有效的.
因此,我认为MSVC的行为不是标准作者的意图,但它可能符合标准的要求.
Mik*_*our 10
这看起来像Visual Studio实现中的一个错误bind
,返回一个只有非const函数调用操作符的类型.它应该返回一个类型,它将所有函数调用转发给绑定的函数对象,而不管它自己的cv资格.
为了总结C++ 11 20.8.9.1.2中相当不透明的语言,对结果的函数调用bind
应该转发到绑定的函数对象,因此如果允许对该对象进行调用则应该允许.因此,如果绑定的函数对象不可调用,那将是一个错误const
; 但在这里,作为一个函数指针,无论cv资格如何,它都是可调用的.
归档时间: |
|
查看次数: |
1279 次 |
最近记录: |