【发布时间】:2017-03-06 10:34:10
【问题描述】:
#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 &Test::operator =(Test &&)'
(25): note: or 'Test &Test::operator =(const Test &)'
(69): 注意:在尝试匹配参数列表时 '(Test, Wrapper)'
========== 构建:0 成功,1 失败,0 最新,0 跳过 ==========
叮当声:
:34:7: 错误:重载运算符“=”的使用不明确(操作数类型为“Test”和“typename std::remove_reference &>::type”(又名“Wrapper”))
test = std::move(wrapperTest); // 适用于 GCC 和 ICC,不适用于 Clang 和 Microsoft Visual C++
~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~
:25:8: 注意:候选函数
Test& operator=(Test const &test) { std::cout
^
:26:8: 注意:候选函数
Test& operator=(Test &&test) { std::cout
^
生成 1 个错误。
【问题讨论】:
-
g++的示例在哪里?您提供了VC++,但您的问题标题为g++。它是哪一个? Visual Studio C++ 是与 GNU g++ 不同的编译器。 -
我很困惑。他们都提到了同一个问题:
operator=()是模棱两可的。那有什么不同? -
@ThomasMatthews 我说这段代码在 GCC 上编译得很好,但在 Clang 和 VC++ 上编译不好,我把 Clang 和 VC++ 的错误信息放在了。
-
@Deduplicator 但是明确的右值转换不会被调用,不是吗?
-
等等,
&和&&函数说明符有什么作用?我第一次见到他们
标签: c++ gcc clang overload-resolution