繁体   English   中英

为什么这个不正确的std :: function初始化使用MSVC编译?

[英]Why does this incorrect std::function initialization compile using MSVC?

今天我遇到了一个有趣的问题。 我创建了一个lambda,它接受对struct的引用,并错误地将它设置为std :: function,它按值接收它的参数。

这是一个更简洁的版本:

#include <functional>

struct InputStruct
{
    int i;
    InputStruct(): i(1){}
};

void function_rcv(std::function<bool(InputStruct)> & func_ref)
{
    InputStruct in;
    func_ref(in);
}


int main()
{
    std::function<bool(InputStruct)> my_func = [](InputStruct & in)->bool{return in.i==1;};
    function_rcv(my_func);
}

godbolt检查显示这与MSVC成功编译,但对于Clang和GCC都失败了。

有趣的是,使用原语而不是结构会在所有三个编译器上编译失败。

这是MSVC编译器中的错误吗?

总结:它不是编译器错误。 MSVC接受此代码是因为其默认的不符合行为,但它可以与交换机标准一致。

首先,我需要澄清std::function的一个方面:它接受一个函数(一般来说, Callable )哪个签名不是完美匹配,但参数可以转换。 考虑:

using intFn = void (int);
void fn(short);

intFn *a = fn;               // doesn't compile
std::function<intFn> b = fn; // compiles!

这里, intFn是一个具有int参数的函数类型,而函数fn具有一个short参数。 简单函数指针a ,不能设置为指向fn ,因为参数的类型不同( int vs short )。 但是, std::function允许这样,所以b可以设置为指向fn

在您的示例中, std::function按值有一个InputStruct参数,而lambda有一个非const左值引用InputStruct & std::function std::forward s它的参数时,它变成一个xvalue,它不能绑定到lambda的左值引用参数。 这就是标准符合编译器不接受此代码的原因。

为什么MSVC接受此代码? 因为默认情况下它具有不符合的行为:它允许将类临时(和xvalues)绑定到非const左值引用。 您可以使用/Zc:referenceBinding (或旧的/Za选项)禁用此行为。 如果您使用此开关,MSVC拒绝您的示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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