#include <iostream>
template <typename T>
struct Wrapper {
operator T const &() const & {
std::cout << "Wrapper::operator T const &() const &\n";
return _obj;
}
operator T&() & {
std::cout << "Wrapper::operator T&() &\n";
return _obj;
}
operator T&&() && {
std::cout << "Wrapper::operator T&&() &&\n";
return std::move(_obj);
}
private:
T _obj;
};
struct Test {
Test& operator=(Test const &test) {
std::cout << "Test& Test::operator=(Test const &)\n";
return *this;
}
Test& operator=(Test &&test) {
std::cout << "Test& Test::operator=(Test &&)\n";
return *this;
}
};
int main() {
Test test;
Wrapper<Test> wrapperTest;
test = wrapperTest; // OK for all
test = std::move(wrapperTest); // OK for GCC and ICC, not for Clang and VC++
return 0;
}
VC ++:
(34):错误C2593:'operator ='不明确
(26):注意:可以是'Test&amp; Test :: operator =(Test&amp;&amp;)'
(25):注意:或'Test&amp; Test :: operator =(const Test&amp;)'
(69):注意:在尝试匹配参数列表'(Test,Wrapper)'
时==========构建:0成功,1失败,0最新,0跳过==========
Clang:
:34:7:错误:使用重载运算符'='是不明确的(操作数类型'Test'和'typename std :: remove_reference&amp;&gt; :: type'(又名'Wrapper'))
test = std :: move(wrapperTest); //适用于GCC和ICC,不适用于Clang和Microsoft Visual C ++
~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~
:25:8:注意:候选功能
测试和安培; operator =(Test const&amp; test){std :: cout&lt;&lt; “Test&amp; Test :: operator =(Test const&amp;)\ n”;返回*这个; }
^
:26:8:注意:候选功能
测试和安培; operator =(Test&amp;&amp; test){std :: cout&lt;&lt; “Test&amp; Test :: operator =(Test&amp;&amp;)\ n”;返回*这个; }
^
生成了1个错误。
答案 0 :(得分:4)
我认为gcc和icc是正确的。
test = std::move(wrapperTest);
将Wrapper<Test>&&
分配给Test
,因为没有候选人匹配此次调用,它会考虑最多需要1次转换的操作。
当用作函数参数并且当函数的两个重载可用时,一个采用rvalue引用参数而另一个采用左值引用const参数,rvalue绑定到rvalue引用重载(因此,如果同时复制和移动构造函数可用,rvalue参数调用移动构造函数,同样使用复制和移动赋值运算符)。
非静态成员函数可以使用左值ref-qualifier(函数名后面的标记&amp;)或rvalue ref-qualifier(标记&amp;&amp;函数名后面)声明。在重载解析期间,类X的非静态cv限定成员函数被视为一个函数,如果它没有ref-qualifiers或者它具有lvalue ref-qualifier,则将带有lvalue类型的隐式参数引用到cv-qualified X 。否则(如果它有rvalue ref-qualifier),它被视为一个函数,它采用类型为rvalue的隐式参数来引用cv-qualified X.
现在,我们有这些候选人:
Test& operator=(Test &&test)
operator T&&() &&
Test& operator=(Test const &test)
operator T const &() const &
根据这些段落,编制者应从Test& operator=(Test &&test)
operator T&&() &&