3

从右值引用和 const 引用编写重载函数时,您可能会出现代码重复,因此我有时会使用相同的代码。如此处所示:

#include <iostream>
#include <type_traits>

struct A {
  template <typename T>
  A& operator=(T&&) {
    if constexpr (::std::is_rvalue_reference_v<T&&>) {
      ::std::cerr << "operator= move\n";
    } else {
      ::std::cerr << "operator= copy\n";
    }
    return *this;
  };
};

现在我的理解是这应该同时实现 anA& operator=(T const&)和 an A& operator=(T&&)。所以给定这段代码,理论上我会期望这个调用:

int main() {
  A a,b;
  a = b;
  a = ::std::move(b);
}

产生以下输出:

operator= copy
operator= move

然而,令我惊讶的是,第二行(!)不见了。我怎样才能同时覆盖两者?


我正在使用 g++ 8.3.0 和-std=c++17.

4

1 回答 1

0

鉴于 1201ProgramAlarm 指出的解释,有趣的问题是为什么它适用于任何一种情况。答案很简单:您分配了一个非const对象,因此T推断为A&(并且T&&也变为A&),产生比接受的隐式复制构造函数严格更好const A&的匹配。对于移动构造函数,或者如果您分配了 a ,则签名是相同的,在这种情况下首选const A非模板。

于 2019-04-25T01:45:21.830 回答