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

oxcyiej7  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(135)
  1. #include <iostream>
  2. struct Obj{ Obj(){} };
  3. struct Obj2{ Obj2(){} };
  4. // option 1
  5. Obj operator+(Obj const& x0, Obj const& x1) { printf("%s\n", "+(const&, const&)"); return Obj{}; }
  6. Obj operator+(Obj const& x0, Obj&& x1) { printf("%s\n", "+(const&, &&)"); return Obj{}; }
  7. Obj operator+(Obj&& x0, Obj const& x1) { printf("%s\n", "+(&&, const&)"); return Obj{}; }
  8. Obj operator+(Obj&& x0, Obj&& x1) { printf("%s\n", "+(&&, &&)"); return Obj{}; }
  9. //option 2
  10. // Obj2 operator+(auto const& x0, auto const& x1) { printf("%s\n", "+(const&, const&)"); return Obj2{}; }
  11. // Obj2 operator+(auto const& x0, auto&& x1) { printf("%s\n", "+(const&, &&)"); return Obj2{}; }
  12. // Obj2 operator+(auto&& x0, auto const& x1) { printf("%s\n", "+(&&, const&)"); return Obj2{}; }
  13. // Obj2 operator+(auto&& x0, auto&& x1) { printf("%s\n", "+(&&, &&)"); return Obj2{}; }
  14. int main()
  15. {
  16. Obj x0;
  17. Obj x1{ x0 };
  18. auto x2 = x0 + x1;
  19. }

字符串
如果我选择选项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)基本上等同于(或等同于写

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

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

  1. template<typename T, typename U>
  2. Obj2 operator+(T const& x0, U const& x1);
  3. template<typename T, typename U>
  4. Obj2 operator+( const& x0, auto&& x1);
  5. template<typename T, typename U>
  6. Obj2 operator+(T&& x0, U const& x1);
  7. template<typename T, typename U>
  8. Obj2 operator+(T&& x0, U&& x1); //this is best match for x0 + x1

展开查看全部

相关问题