Khi nào là các hàm thành viên đặc biệt (cụ thể, sao chép/di chuyển các nhà xây dựng và sao chép/di chuyển các toán tử gán) của một lớp mẫu được khởi tạo? Ngay khi bản thân lớp được khởi tạo, hoặc chỉ khi chúng cần thiết?Khi nào các hàm thành viên đặc biệt của một lớp mẫu được khởi tạo?
này đi lên trong tình huống sau đây:
template <class T, class U>
struct pair
{
T first;
U second;
pair() : first(), second() {}
pair(const pair&) = default;
};
struct S
{
S() {}
S(const S&) = delete;
S(S&&) = default;
};
int main()
{
pair<int, S> p;
}
Clang từ chối để biên dịch mã này, với các lỗi sau đây:
test.cpp:9:5: error: the parameter for this explicitly-defaulted copy constructor is const, but a member or base requires it to be
non-const
pair(const pair&) = default;
^
test.cpp:21:18: note: in instantiation of template class 'pair<int, S>' requested here
pair<int, S> p;
^
gợi ý rằng nó sẽ cố gắng để nhanh chóng các constructor sao chép càng sớm càng lớp được khởi tạo.
GCC, tuy nhiên, biên dịch mã chỉ tốt, cho thấy rằng nó sẽ chỉ cố gắng để khởi tạo các nhà xây dựng bản sao nếu nó thực sự cần thiết.
Hành vi của trình biên dịch nào là chính xác?
(. Một sự khác biệt tương tự được trưng bày cho toán tử gán)
CẬP NHẬT: Đây có gì để làm với thực tế là các nhà xây dựng bản sao của pair
trong ví dụ này là default
ed, bởi vì nếu tôi thay đổi định nghĩa của nó đến số
pair(const pair& p) : first(p.first), second(p.second) {}
thì mã cũng được chuyển.
Biên dịch tốt bằng clang3.0 với -std = C++ 11. –