为什么我的operator =(T &&)模板仅绑定到const&而不绑定到&&?

时间:2019-04-25 00:03:59

标签: c++ templates rvalue-reference const-reference

当从右值引用和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;
  };
};

现在,我的理解是,这应该同时实现A& operator=(T const&)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进行编译。

1 个答案:

答案 0 :(得分:0)

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