2010-03-01 13 views
8

Défi:Pourquoi cette définition distincte provoque-t-elle une erreur?

J'ai ce code qui ne parvient pas à compiler. Pouvez-vous comprendre ce qui ne va pas? Ça m'a fait mal à la tête une fois.

// header 
namespace values { 
    extern std::string address; 
    extern int port; 
} 

// .cpp file 
std::string ::values::address = "192.0.0.1"; 
int   ::values::port = 12; 

Cela semble correct dès la première vue. Combien et quelles sont les erreurs?

+0

Qu'a dit le compilateur? –

+0

Connaissez-vous déjà la réponse? Il semble que ce soit;) –

+0

@Nikolai, il est plus difficile d'essayer sans xD –

Répondre

8

une erreur:

std::string values::address = "192.0.0.1"; 

est la forme appropriée, sinon l'analyse syntaxique est

std::string::values::address = "192.0.0.1"; 

et il n'y a pas de membre "valeurs" avec un membre "adresse" à l'intérieur "string" ..

cela fonctionnera pour les types intégrés, car ils ne peuvent jamais contenir de membres .. donc int :: values ​​est une analyse unambigous, int :: values, car le précédent n'a pas de sens.

std::string (::values::address) = "192.0.0.1"; 

fonctionne aussi. Notez que si vous typedef int sometype; que vous auriez le même problème en utilisant sometype que vous faites avec la chaîne ci-dessus, mais pas avec "int".

+0

hah, vous êtes le gagnant. Neat :) –

+0

corrigé. selon la correction de litb. –

3

Je suis en retard au jeu, mais je l'aurais préféré écrire le fichier .cpp comme:

// .cpp file 
namespace values { 
    std::string address = "192.0.0.1"; 
    int   port = 12; 
} 

Bien sûr, cela ne résout pas le problème que vous aviez avec la déclaration friend.

+0

Je soupçonne mon premier exemple avec l'adresse "truc" était boiteux :) L'exemple d'ami est beaucoup mieux. Je suis d'accord avec toi que ce mode de définition est le meilleur :) –