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