2013-06-13 40 views
5
#include <iostream> 

namespace Foo 
{ 
    class Baz { }; 

    std::ostream& operator<< (std::ostream& ostream , const Baz& baz) 
    { 
     return ostream << "operator<<\n"; 
    } 
} 

int main() 
{ 
    std::cout << Foo::Baz(); 
} 

Tôi xác định một operator<< trong không gian tên Foo. Tại sao nó có thể được gọi từ phạm vi toàn cầu?Hiểu phạm vi của các toán tử trong C++

Trả lời

9

DRTL

Trình biên dịch có thể tìm thấy người dùng định nghĩa operator<< qua tra cứu luận phụ thuộc vào.

Giải thích

Cuộc gọi

std::cout << Foo::Baz(); 

thực sự là một tốc ký ghi vào cho

operator<<(std::cout, Foo::Baz()); 

Bởi vì cuộc gọi chức năng là không đủ tiêu chuẩn (tức là không có tiền tố namespace hoặc ngoặc xung quanh), trình biên dịch sẽ không chỉ làm tên bình thường tra cứu (ra phía ngoài từ phạm vi chức năng địa phương), mà còn tra cứu luận phụ thuộc (còn được gọi ADL) cho quá tải khác của chức năng operator<< trong tất cả các namespaces liên của cả hai lập luận std::cout và lớp Baz. Các không gian tên được kết hợp này là stdFoo trong trường hợp này.

tra cứu Như vậy lập luận phụ thuộc sẽ tìm thấy các định nghĩa

std::operator<<(std::ostream&, /* all the builtin types and Standard strings and streams */) 
Foo::operator<<(std::ostream&, const& Baz) 

Sau khi tên-lookup, luận khấu trừ sẽ thất bại cho tất cả các std::operator<< quá tải. Đây là lý do tại sao độ phân giải quá tải sẽ thấy rằng người dùng xác định Foo::operator<< thực ra là kết hợp duy nhất. Đó là lý do tại sao nó được gọi.

+0

TemplateRex, cảm ơn bạn rất nhiều vì đã có câu trả lời toàn diện! – Kolyunya

+0

@Kolyunya Rất vui khi được giúp đỡ! – TemplateRex

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