Giả sử bạn có các lớp sau:Tại sao không thể khởi tạo cặp với hàm tạo bản sao "non const" trong khi nó có thể khởi tạo một cặp mà không có?
struct A {
A() {}
A (A &) = delete;
};
int main() {
std::pair<A, int> p1;
return 0;
}
Đoạn mã dưới đây sẽ thất bại để biên dịch (sử dụng -std=c++11
với g++
) với các lỗi sau:
/usr/include/c++/5/bits/stl_pair.h: In instantiation of ‘struct std::pair’:
test.cpp:13:23: required from here
/usr/include/c++/5/bits/stl_pair.h:127:17: error: ‘constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = A; _T2 = int]’ declared to take const reference, but implicit declaration would take non-const
constexpr pair(const pair&) = default;
Theo thông báo lỗi, tôi sẽ giả định rằng điều này là do không thể instanciate constructor sao chép mặc định vì vòng loại const
trên đối số std::pair
.
Tôi có thể hiểu lý do tại sao điều này sẽ không biên dịch mà không có = delete
, bởi vì nó không thể instanciate các nhà xây dựng bản sao có một tham số std::pair const&
.
Nhưng với = delete
, tôi hy vọng trình biên dịch sẽ không khởi tạo trình xây dựng như vậy vì nó không thể (theo như tôi hiểu). Trên thực tế, nhà xây dựng bản sao này sẽ bị xóa như thể hiện bởi đoạn mã này:
std::pair<A, int> p1;
decltype(p1) p2(p1);
Những thất bại:
test.cpp:11:23: error: use of deleted function ‘constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = A; _T2 = int]’
decltype(p1) p2(p1);
Về cơ bản, câu hỏi của tôi là: Tại sao các trình biên dịch thất bại trong việc tạo một constructor sao chép xóa của std::pair
?
Xem http://cplusplus.github.io/LWG/lwg-closed.html#2068 –