【问题标题】:Why does my operator=(T&&) template only bind to a const& but not a &&?为什么我的 operator=(T&&) 模板只绑定到 const& 而不是 &&?
【发布时间】:2019-09-14 08:13:21
【问题描述】:

从右值引用和 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&amp; operator=(T const&amp;)A&amp; operator=(T&amp;&amp;)。所以给定这段代码,理论上我会期望这个调用:

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

产生以下输出:

operator= copy
operator= move

但是,令我惊讶的是,第二行 (!) 不见了。如何同时覆盖两者?


我正在使用 g++ 8.3.0 和 -std=c++17 进行编译。

【问题讨论】:

  • 看到这个similar question
  • @1201ProgramAlarm 哦,这简直是邪恶的!他们到底为什么要这样做?!无论如何,谢谢。
  • @bitmask 我怀疑是因为复制/移动构造函数和赋值运算符具有特定属性,并且使某些模板实例化“特殊”是一堆没人愿意打开的蠕虫。

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


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2012-09-04
    • 2021-11-06
    • 2012-08-02
    • 2019-06-26
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 2010-11-10
    • 2020-01-31
    相关资源
    最近更新 更多