繁体   English   中英

C ++ 11是否要求将此lambda声明为可变?

[英]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]> cdecl 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使函数类型不同;我'我很确定这是一个错误。)

这不是关于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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM