c++ 为什么在使用auto时+运算符默认为右值重载?

oxcyiej7  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(109)
#include <iostream>

struct Obj{ Obj(){} };
struct Obj2{ Obj2(){} };

// option 1
Obj operator+(Obj const& x0, Obj const& x1) { printf("%s\n", "+(const&, const&)"); return Obj{}; }
Obj operator+(Obj const& x0, Obj&& x1) { printf("%s\n", "+(const&, &&)"); return Obj{}; }
Obj operator+(Obj&& x0, Obj const& x1) { printf("%s\n", "+(&&, const&)"); return Obj{}; }
Obj operator+(Obj&& x0, Obj&& x1) { printf("%s\n", "+(&&, &&)"); return Obj{}; }

//option 2
// Obj2 operator+(auto const& x0, auto const& x1) { printf("%s\n", "+(const&, const&)"); return Obj2{}; }
// Obj2 operator+(auto const& x0, auto&& x1) { printf("%s\n", "+(const&, &&)"); return Obj2{}; }
// Obj2 operator+(auto&& x0, auto const& x1) { printf("%s\n", "+(&&, const&)"); return Obj2{}; }
// Obj2 operator+(auto&& x0, auto&& x1) { printf("%s\n", "+(&&, &&)"); return Obj2{}; }

int main()
{
    Obj x0;
    Obj x1{ x0 };
    auto x2 = x0 + x1;
}

字符串
如果我选择选项1,我会得到(const&,const&),因为x 0和x1显然是左值。但是,如果我选择选项2,它会调用(&&,&&)重载,并认为x 0和x1是右值?!为什么会发生这种情况?严肃的问题。它是否应该选择更受约束的版本,而忽略选项2?即便如此,当x 0和x1总是左值时,我选择什么选项还重要吗?

j5fpnvbx

j5fpnvbx1#

但是,如果我选择选项2,它会调用(&&,&&)重载,并认为x 0和x1是右值?!为什么会发生这种情况?
这是因为在选项2中,重载运算符实际上是“模板化”的(也称为缩写函数模板),并且表现得像你有template<typename T, typename U> operator+( T&&, U&&)等,其中有forwarding references,并且在所有四个重载中,最后一个重载版本Obj2 operator+(auto&& x0, auto&& x1);是调用x0 + x1最佳匹配
例如,Obj2 operator+(auto&& x0, auto&& x1)基本上等同于(或等同于写

template<typename T, typename U>
Obj2 operator+(T&& x0, U&& x1)

字符串
这意味着你实际上拥有的是:

template<typename T, typename U>
Obj2 operator+(T const& x0, U const& x1);
template<typename T, typename U>
Obj2 operator+( const& x0, auto&& x1);
template<typename T, typename U>
Obj2 operator+(T&& x0, U const& x1);
template<typename T, typename U>
Obj2 operator+(T&& x0, U&& x1); //this is best match for x0 + x1

相关问题