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

definisco un operator<< nel Foo namespace. Perché può essere chiamato dall'ambito globale?Comprendere la portata degli operatori in C++

risposta

9

DRTL

Il compilatore può trovare il definita dall'utente operator<< attraverso argomento-dipendente di ricerca.

Spiegazione

La chiamata

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

è in realtà una scorciatoia infisso per

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

Poiché la chiamata di funzione è qualificato (ovvero senza alcun prefisso namespace o parentesi circostanti), il compilatore non farà solo nome ordinario ricerca (all'esterno dall'ambito funzione locale), ma anche ricerca argomento-dipendente (a.k.a ADL) per altri sovraccarichi di funzione operator<< di tutte le namespace associati di entrambi gli argomenti std::cout e classe Baz. Questi spazi dei nomi associati sono std e Foo in questo caso.

ricerca Così argomento-dipendente potrete trovare le definizioni

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

Dopo nome-lookup, argomento deduzione fallirà per tutti i std::operator<< sovraccarichi. Questo è il motivo per cui la risoluzione di sovraccarico troverà che l'utente Foo::operator<< è in realtà l'unica corrispondenza. Ecco perché è chiamato.

+0

TemplateRex, grazie mille per una risposta completa! – Kolyunya

+0

@ Kolyunya Felice di essere stato di aiuto! – TemplateRex