为什么“推导此”模板给出的结果与通过右值/左值重载不同?

问题描述 投票:0回答:1

我编写了这个简单的测试来根据

this
是右值还是左值进行重载。最初的版本有额外的情况,但我将其减少到令我困惑的情况。

#include <iostream>

struct A {
  int pp=0;  
  A(int p) : pp(p) {}
  A &prop(int nn) & {pp=nn; return *this;}
  A &&prop(int nn) && {pp=nn; return std::move(*this);}
};

struct B {
  B(const A &aa) {std::cout << "COPY: " << aa.pp << std::endl;}
  B(A &&aa) {std::cout << "MOVE: " << aa.pp << std::endl;}
};

int main() {
  A aa(99);
  B b4(aa.prop(33).prop(4));    // 4 COPY
  std::cout << "4 == " << aa.pp << std::endl;

  return 0;
}

输出是我所期望的

COPY: 4
4 == 4

到目前为止,一切都很好。然后我修改了

A
以使用推导
this
的方法:

struct A {
  int pp=0;  
  A(int p) : pp(p) {}

  template <typename self> A prop(this self &&me, int nn) {
    me.pp=nn;
    return me;
  }
};

我期望得到相同的结果,但我没有:

MOVE: 4
4 == 33
  1. 为什么第二个版本要调用move方法?

  2. 即使它调用了 move 方法,我仍然希望看到

    nn
    设置为 4 而不是 33。

发生什么事了?

c++ c++23
1个回答
2
投票

在“推导这个”的情况下,你总是按值返回一个

A
对象,所以:

aa.prop(33).prop(4)

33
分配给
aa.pp
,然后
prop(4)
部分将
4
分配给刚刚返回的
pp
copy
aa
,从而将
aa.pp
保留为
33

您需要做的是返回

A&
A&&
引用,具体取决于
this
的推导方式。 为此,您可以使用
decltype(auto)
来推断返回对象的值类别并返回正确的类型。

© www.soinside.com 2019 - 2024. All rights reserved.