5

Tôi có đoạn mã ngắn này mà tôi muốn có thêm thông tin về việc tại sao quá tải phân giải lại chọn một hàm tạo khác. Đây là mã được đề cập:Độ phân giải quá tải C++ Constructor với nhiều thừa kế

#include <iostream> 

struct Base 
{ 

}; 

struct Other 
{ 
    Other(const Other&) 
    { 
     std::cout << "Copy Constructor\n"; 
    } 
    Other(const Base&) 
    { 
     std::cout << "Custom Constructor\n"; 
    } 
}; 

struct Derived : public Base, public Other 
{ 
    Derived() : 
     Other(*this) 
    { 

    } 
}; 

int main() 
{ 
    Derived derived; // Prints "Copy Constructor" 

    system("pause"); 
    return 0; 
} 

Tôi giả sử có một phần trong tiêu chuẩn C++ xác định hàm tạo bản sao là đối sánh tốt hơn so với các hàm tạo do người dùng xác định *? Giả sử của tôi khác là nếu không có quy tắc nào ưu tiên constructor sao chép tồn tại, thì trình biên dịch sẽ đi theo thứ tự kế thừa (như với thứ tự xây dựng với nhiều thừa kế) hoặc chỉ cho tôi một lỗi gọi hàm dựng không rõ ràng. Tuy nhiên, đảo ngược thứ tự mà trong đó Derived kế thừa từ BaseOther không thay đổi đầu ra, điều này dẫn tôi tin rằng dự đoán ban đầu của tôi về các nhà thầu sao chép được ưu tiên là chính xác. Có ai có thể chỉ cho tôi quy tắc xác định hành vi mà tôi thấy không?

* Tôi đã kiểm tra cppreference.com's Overload Resolution page, nhưng tôi không thấy bất kỳ quy tắc nào được liệt kê ở đó sẽ giải thích hành vi tôi thấy (mặc dù tôi là không hoàn toàn thông thạo Standardese, vì vậy tôi có thể dễ dàng bỏ qua nó).

+3

Gọi mơ hồ cho clang/gcc [Demo] (http://coliru.stacked-crooked.com/a/0319bddd762f37aa) – Jarod42

+0

Cuộc gọi mơ hồ trong trình biên dịch của tôi, sẽ không biên dịch. – iheanyi

+1

Huh, thú vị. Tôi đang sử dụng Visual Studio 2017.3 (Preview), và nó biên dịch ngay cả với cờ/permissive. Tôi giả định đó là hành vi phi tiêu chuẩn từ Visual Studio hơn là hành vi không chuẩn từ Clang/GCC? –

Trả lời

1

Lý do đoạn mã trong câu hỏi biên dịch là do hành vi tuân thủ không chuẩn từ Visual Studio (Tôi hiện đang sử dụng bản xem trước VS2017.3, biên dịch mã không có lỗi ngay cả với cờ/permissive). Dưới đây là các lỗi phát ra bởi GCC và Clang:

GCC

Error(s): 
source_file.cpp: In constructor ‘Derived::Derived()’: 
source_file.cpp:25:20: error: call of overloaded ‘Other(Derived&)’ is ambiguous 
     Other(*this) 
        ^
source_file.cpp:16:5: note: candidate: Other::Other(const Base&) 
    Other(const Base&) 
    ^
source_file.cpp:12:5: note: candidate: Other::Other(const Other&) 
    Other(const Other&) 
    ^

Clang

Error(s): 
source_file.cpp:25:9: error: call to constructor of 'Other' is ambiguous 
     Other(*this) 
     ^ ~~~~~ 
source_file.cpp:12:5: note: candidate constructor 
    Other(const Other&) 
    ^
source_file.cpp:16:5: note: candidate constructor 
    Other(const Base&) 
    ^
1 error generated. 

Lỗi đầu ra lấy từ http://rextester.com/.

Các vấn đề liên quan