2013-06-13 5 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(); 
} 

я определить в Foo пространством имен operator<<. Почему он может быть вызван из глобальной сферы?Понимание сферы операторов в C++

ответ

9

DRTL

Компилятор может найти определенный пользователем operator<< через аргумента-зависимого поиска.

Объяснение

Вызов

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

на самом деле является инфиксным сокращение для

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

Поскольку вызов функции неквалифицированным (т.е. без какого-либо префикса пространства имен или окружающих скобок), компилятор будет не только делать обычного поиск имени (наружу из локальной области видимости функции), но также и аргумент-зависимого поиск (a.k.a ADL) для других перегрузок функции operator<< во всех пространствах имен, связанных обоего аргументов std::cout и класса Baz с. Эти ассоциированные пространства имен в этом случае равны std и Foo.

Таким образом, аргумент-зависимый поиск будет найти определения

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

После именин поиска, вывод аргумента потерпит неудачу для всех std::operator<< перегрузок. Вот почему перегрузочное разрешение найдет, что определяемый пользователем Foo::operator<< на самом деле является единственным совпадением. Вот почему это называется.

+0

TemplateRex, большое спасибо за исчерпывающий ответ! – Kolyunya

+0

@ Kolyunya Рад помочь! – TemplateRex

Смежные вопросы