【发布时间】:2019-07-14 15:06:42
【问题描述】:
今天遇到了一个有趣的问题,由我自己的错字开始。我创建了一个 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 编译器中的错误吗?
【问题讨论】:
-
在我看来是个错误。
-
@NathanOliver 有趣的东西。如果有机会,我必须向 Microsoft 提交错误。
-
这只是通常的“MSVC 允许临时绑定到左值引用”。用
/Zc:referenceBinding编译不会编译。 -
@SergeyA 我相信关于构造函数 5 的注释是有原因的(此构造函数不参与重载决议,除非 f 对于参数类型
Args...和返回类型R是可调用的。)。std::function<bool(InputStruct)>可以采用右值,但[](InputStruct & in)->bool不能,所以它应该会失败。 -
@SergeyA 如果它们是左值,那当然。问题是
std::function的operator()将为底层函数对象调用INVOKE<R>(f, std::forward<Args>(args)...),如果将右值传递给operator(),那么底层函数对象将获得一个右值,它不能绑定到左值引用。
标签: c++ c++11 gcc visual-c++