2016-12-29 13 views
6
void f() {} 

namespace test 
{ 
void f(int) {}  
void g() { f(); } // error in gcc 6.2.0 
} 

int main() 
{ 
    test::g(); 
} 

Biên dịch nó với g ++ -std = C++ 1Z main.cpp, đầu ra là như sau:Tại sao gcc ẩn các hàm bị quá tải trong không gian tên chung?

main.cpp: In function 'void test::g()': 
main.cpp:9:4: error: too few arguments to function 'void test::f(int)' 
    f(); // error in gcc 
    ^
main.cpp:5:6: note: declared here 
void f(int) {} 

trình biên dịch của tôi là gcc 6.2.0.

Tại sao gcc ẩn các chức năng quá tải trong không gian tên chung? Điều này có phù hợp với tiêu chuẩn C++ không?

Trả lời

12

Tại sao gcc ẩn các chức năng quá tải trong không gian tên chung? Điều này có phù hợp với tiêu chuẩn C++ không?

Có. Tóm lại, bạn không thể quá tải các chức năng thông qua các phạm vi khác nhau. Theo quy tắc unqualified name lookup, để gọi f() trong g(), tên f có thể được tìm thấy bên trong không gian tên test, khi đó việc tra cứu tên sẽ dừng lại; overload resolution diễn ra sau đó (dựa trên tên được tìm thấy). Điều đó có nghĩa là f() trong không gian tên chung sẽ không được xem xét chút nào ngay cả khi nó có vẻ thích hợp hơn ở đây.

(tôi nhấn mạnh)

Đối với một cái tên không đủ tiêu chuẩn, đó là một cái tên không xuất hiện để các bên phải của một nhà điều hành giải quyết phạm vi ::, tra cứu tên xem xét phạm vi như mô tả dưới đây, cho đến khi tìm thấy ít nhất một tuyên bố của bất kỳ loại nào, tại thời điểm đó, quá trình tra cứu dừng lại và không có phạm vi nào khác được xem xét .

Để biên dịch một cuộc gọi chức năng, đầu tiên trình biên dịch phải thực hiện tra cứu tên, trong đó, cho các chức năng, có thể liên quan đến tranh luận phụ thuộc vào tra cứu, và cho chức năng mẫu có thể được theo sau bởi mẫu khấu trừ đối số. Nếu các bước này tạo ra nhiều hơn một ứng cử viên chức năng, thì quá trình phân giải quá tải được thực hiện để chọn chức năng mà thực sự sẽ được gọi.

Bạn có thể sử dụng using để giới thiệu tên vào cùng một phạm vi, tức là làm cho chúng trở thành các hàm quá tải thực tế.

namespace test 
{ 
    using ::f;  // introduce the name from global namespace 
    void f(int) {}  
    void g() { f(); } // fine 
} 
+2

tl; dr: đây là một ẩn danh C++ đã biết, và cùng một lý do rằng ["quá tải" trong lớp dẫn xuất ẩn biến thể trong một lớp cơ sở] (http://stackoverflow.com/q/1628768/560648), yêu cầu 'sử dụng Base :: foo' trong một số trường hợp. –

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