Tôi nhận được lỗi sau:quá tải nhập nhằng cho 'operator =' với C++ 11 std :: di chuyển và sao chép và hoán đổi thành ngữ
[matt ~] g++ -std=c++11 main.cpp -DCOPY_AND_SWAP && ./a.out
main.cpp: In function ‘int main(int, const char* const*)’:
main.cpp:101:24: error: ambiguous overload for ‘operator=’ in ‘move = std::move<Test&>((* & copy))’
main.cpp:101:24: note: candidates are:
main.cpp:39:7: note: Test& Test::operator=(Test)
main.cpp:52:7: note: Test& Test::operator=(Test&&)
Khi đoạn mã sau được biên soạn:
#include <iostream>
#include <unordered_map>
class Test final {
public:
typedef std::unordered_map<std::string, std::string> Map;
public:
Test();
explicit Test(Map&& map);
~Test();
Test(const Test& other);
Test(Test&& test);
#ifdef COPY_AND_SWAP
Test& operator=(Test other);
#else
Test& operator=(const Test& other);
#endif
Test& operator=(Test&& other);
size_t Size() const noexcept;
friend void swap(Test& lhs, Test& rhs);
private:
friend std::ostream& operator<<(std::ostream& stream, const Test& test);
private:
Map map_;
};
Test::Test() : map_() {
std::cerr << "Default constructor called" << std::endl;
};
Test::Test(const Test& other) : map_(other.map_) {
std::cerr << "Copy constructor called" << std::endl;
};
Test::Test(Test&& other) : map_(std::move(other.map_)) {
std::cerr << "Move constructor called" << std::endl;
};
Test::Test(Map&& map) : map_(std::move(map)) {
std::cerr << "Map constructor called" << std::endl;
};
Test::~Test() {};
#ifdef COPY_AND_SWAP
Test& Test::operator=(Test other) {
std::cerr << "Copy and swap assignment called" << std::endl;
using std::swap;
swap(this->map_, other.map_);
return *this;
}
#else
Test& Test::operator=(const Test& other) {
std::cerr << "Copy assignment called" << std::endl;
this->map_ = other.map_;
return *this;
}
#endif
Test& Test::operator=(Test&& other) {
std::cerr << "Move assignment called" << std::endl;
this->map_ = other.map_;
other.map_.clear();
return *this;
}
size_t Test::Size() const noexcept {
return map_.size();
}
void swap(Test& lhs, Test& rhs) {
using std::swap;
swap(lhs.map_, rhs.map_);
}
std::ostream& operator<<(std::ostream& stream, const Test& test) {
return stream << test.map_.size();
}
int main (const int argc, const char * const * const argv) {
using std::swap;
Test::Map map {
{"some", "dummy"},
{"data", "to"},
{"fill", "up"},
{"the", "map"}
};
std::cout << " map size(): " << map.size() << std::endl;
std::cout << "Constructing" << std::endl;
Test test(std::move(map));
std::cout << " map.size(): " << map.size() << std::endl;
std::cout << "test.Size(): " << test.Size() << std::endl;
std::cout << "Copy construction" << std::endl;
Test copy(test);
std::cout << "copy.Size(): " << copy.Size() << std::endl;
std::cout << "Move construction" << std::endl;
Test move(std::move(copy));
std::cout << "move.Size(): " << move.Size() << std::endl;
std::cout << "copy.Size(): " << copy.Size() << std::endl;
std::cout << "Swapping" << std::endl;
swap(move, copy);
std::cout << "move.Size(): " << move.Size() << std::endl;
std::cout << "copy.Size(): " << copy.Size() << std::endl;
std::cout << "Swapping back" << std::endl;
swap(move, copy);
std::cout << "move.Size(): " << move.Size() << std::endl;
std::cout << "copy.Size(): " << copy.Size() << std::endl;
std::cout << "Copy assignment" << std::endl;
copy = test;
std::cout << "test.Size(): " << test.Size() << std::endl;
std::cout << "copy.Size(): " << copy.Size() << std::endl;
std::cout << "Move assignment" << std::endl;
move = std::move(copy);
std::cout << "move.Size(): " << move.Size() << std::endl;
std::cout << "copy.Size(): " << copy.Size() << std::endl;
return 0;
}
khi biên soạn với g++ -std=c++11 main.cpp && ./a.out
:
[matt ~] g++ -std=c++11 main.cpp && ./a.out
map size(): 4
Constructing
Map constructor called
map.size(): 0
test.Size(): 4
Copy construction
Copy constructor called
copy.Size(): 4
Move construction
Move constructor called
move.Size(): 4
copy.Size(): 0
Swapping
move.Size(): 0
copy.Size(): 4
Swapping back
move.Size(): 4
copy.Size(): 0
Copy assignment
Copy assignment called
test.Size(): 4
copy.Size(): 4
Move assignment
Move assignment called
move.Size(): 4
copy.Size(): 0
có thể ai đó giúp tôi hiểu tại sao sự nhập nhằng xảy ra khi sử dụng sao chép và hoán đổi thành ngữ trong trường hợp này?
+1. Và giải pháp cho vấn đề là loại bỏ nhà điều hành chuyển nhượng, bản sao và trao đổi xử lý các giá trị _and_ lvalues, đó là điểm –
@JonathanWakely tnx, được cập nhật. – TemplateRex
@rhalbersma Cảm ơn câu trả lời. Tôi rõ ràng có nhiều hiểu hơn về lý do tại sao các chuỗi chuyển đổi tiềm ẩn giống nhau bằng cách hiểu giá trị hơn –