繁体   English   中英

防止 lambda 的返回类型扣除

[英]prevent return type deduction of lambda

下面的代码由于自动扣除从 lambda 返回的类型,无法编译。

在没有尾随类型的 C++14 语法术语中,防止这种扣除的正确方法是什么?

编译错误是关于 test() 输入上的不兼容类型(右值),它需要非常量引用

struct B {
    int i;
};

struct A {
    B &getB() { return b; }
private:
    B b;
};

void test(B &b)  {
    b.i++;
}

int main() {
    A a;

    test([&a]() { 
        return a.getB();
    });
    return 0;
}

这里有两个问题。


首先,您实际上并没有调用 lambda,因此不是将返回值传递给test ,而是传递 function object,这显然是一个完全不兼容的类型! 通过在 lambda 之后添加()来调用它,从而将返回值传递给test()来解决这个问题。

[](){ return 42; } ();
//                 ^^ now the whole expression has value 42

其次,您是对的,推导的返回类型将是B ,而不是B& ,并且临时 object 可能不会绑定到test(B&)的 ref-to-non- const参数。

解决此问题的一种方法是使用尾随返回类型来强制引用:

    [&a]() -> B& { .... }

你似乎知道这一点,但不想这样做。 为什么?

另一种选择是返回引用包装器,然后按值返回,但行为类似于引用:

return std::ref(a.getB()));

另一种选择是更改test以能够接受一些临时的。 由于您需要它才能修改原始 object,因此您可以test指针或具有引用语义的其他类型(智能指针、 std::reference_wrapper<B> ,使B在复制时具有引用语义, ...)

void test(B* b) {
    ++(b->i);
}
...
test([&]() { return &a.getB(); } () );

学究的注意事项:我知道++(b->i)中的括号并不是绝对必要的。 我觉得更清楚。

暂无
暂无

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

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