gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:29:42 29 4
gpt4 key购买 nike

今天遇到一个有趣的问题,由我自己的错字引起。我创建了一个 lambda,它接收对结构的引用,并错误地将其设置为 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 有一个非常量左值引用 InputStruct &。当 std::function std::forward 为其参数时,它成为一个 xvalue,它不能绑定(bind)到 lambda 的左值引用参数。这就是符合标准的编译器不接受此代码的原因。

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

关于c++ - 为什么这个不正确的 std::function 初始化使用 MSVC 编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54794587/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com