从函数调用传递值时,std :: tie因“无法绑定非常量左值引用”而失败

Joh*_*nck 3 c++ compiler-errors lvalue c++11

我希望此代码能正常工作,但无法编译:

#include <tuple>

struct S
{
    int x = 0;
    int y() const { return 1; }
};

bool f(const S& a, const S& b)
{
    return std::tie(a.x, a.y()) < std::tie(b.x, b.y());
}
Run Code Online (Sandbox Code Playgroud)

GCC 9说:

错误:无法将类型为'int&'的非常量左值引用绑定到类型为'int'的右值

return std::tie(a.x, a.y()) < std::tie(b.x, b.y());
                     ~~~^~
Run Code Online (Sandbox Code Playgroud)

代码有什么问题,如何解决,为什么?我正在尝试编写一个简洁的比较功能,通常会std::tie支持该功能(实际上这是的教科书用例std::tie)。

演示:https//godbolt.org/z/cWbQC0

Sto*_*ica 6

std::tie总是期望使用左值作为参数,因为其预期目的将在赋值中使用。要处理其他值类别,可以使用std::forward_as_tuple

bool f(const S& a, const S& b)
{
    return std::forward_as_tuple(a.x, a.y()) < std::forward_as_tuple(b.x, b.y());
}
Run Code Online (Sandbox Code Playgroud)

现在,两个元组包含右值引用,这些引用绑定到对的调用结果S::y。毋庸置疑,使用对象时最好注意对象的寿命。


jro*_*rok 5

std::tie将左值引用作为参数,因此无法绑定int返回S::y。您可以使用完美的转发版本,std::forward_as_tuple, 代替:

#include <tuple>

struct S
{
    int x = 0;
    int y() const { return 1; }
};

bool f(const S& a, const S& b)
{
    return std::forward_as_tuple(a.x, a.y()) < std::forward_as_tuple(b.x, b.y());
}
Run Code Online (Sandbox Code Playgroud)

演示。