Sự cố này dựa trên mã hoạt động với tôi trên GCC-4.6 nhưng không cho người dùng khác có CLang-3.0, cả ở chế độ C++ 0x.Xung đột giữa hàm tạo bản sao và hàm tạo chuyển tiếp
template <typename T>
struct MyBase
{
//protected:
T m;
template <typename Args...>
MyBase(Args&& ...x) : m(std::forward<Args>(x)...) {}
};
Một đối tượng của MyBase
có thể mất bất kỳ danh sách các đối số nhà xây dựng, miễn là T
hỗ trợ chữ ký xây dựng. Vấn đề phải làm với các hàm thành viên đặc biệt.
- IIUC, mẫu nhà xây dựng hủy bỏ hàm tạo mặc định được tự động xác định. Tuy nhiên, vì mẫu có thể chấp nhận 0 đối số, mẫu sẽ hoạt động như một hàm tạo mặc định được xác định rõ ràng (miễn là
T
là cấu hình mặc định). - IIUC, việc xác định chính sách sao chép xây dựng của lớp sẽ bỏ qua các mẫu của nhà xây dựng. Điều đó có nghĩa là trong trường hợp này,
MyBase
sẽ nhận được một hàm tạo bản sao được xác định tự động (miễn làT
có thể sao chép được) sẽ kênhT
sao chép-xây dựng. - Áp dụng bước trước đó để di chuyển-xây dựng.
Vì vậy, nếu tôi chuyển một đối số constructor duy nhất, hàm tạo nào được gọi, chuyển tiếp hoặc sao chép ngầm?
typedef std::vector<Int> int_vector;
typedef MyBase<int_vector> VB_type;
int_vector a{ 1, 3, 5 };
VB_type b{ a };
VB_type c{ b }; // which constructor gets called
Sự cố của người dùng của tôi đã sử dụng điều này làm lớp cơ sở. Trình biên dịch phàn nàn rằng lớp của anh ta không thể tổng hợp một hàm tạo bản sao được xác định tự động, bởi vì nó không thể tìm thấy một kết hợp với khuôn mẫu hàm tạo của lớp cơ sở. Không nên gọi số MyBase
bản sao tự động-constructor cho công cụ tạo bản sao tự động của chính nó? CLang có lỗi khi đưa ra xung đột không?
Câu hỏi thú vị. Tôi khuyên bạn nên thực hiện một sscce (xem http://sscce.org/) mà làm việc trong GCC và thất bại trong CLang để giúp chúng tôi hiểu vấn đề tốt hơn và tái tạo lại nó. Ngoài ra, vui lòng cung cấp cho chúng tôi thông báo lỗi chính xác từ CLang. –
Thực ra, phiên bản gcc tương đối gần với đầu (tính đến 20120202) cũng không chấp nhận mã này. Có vẻ như nhà xây dựng chuyển tiếp đang được chọn ngay cả đối với bản sao. Tôi không hoàn toàn chắc chắn tại sao điều này. Nó không liên quan đến "cú pháp khởi tạo đồng bộ": ngay cả khi sử dụng dấu ngoặc đơn cho khai báo cuối cùng nó không biên dịch. –
Mã của tôi là một cái gì đó tôi đã viết một thập kỷ trước cho Tăng cường và cập nhật cho C++ 11 tuần trước. Tôi không biết cách làm việc với tất cả hệ thống Trac của Boost, nhưng bạn có thể xem [những thay đổi của tôi] (https://svn.boost.org/trac/boost/changeset/76982) và [current state] (http) : //svn.boost.org/svn/boost/trunk/boost/utility/base_from_member.hpp) của tập tin (tại phiên bản 77031 tại văn bản này). – CTMacUser