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

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

从右值引用和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进行编译。

c++ templates rvalue-reference const-reference
1个回答
0
投票

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

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