2011-02-02 7 views
7

Le bit de code suivant ne parvient pas à être compilé. L'erreur semble être une sorte d'appel ambigu à la routine de fusion. Ma compréhension est que STL a une routine de fusion trouvée dans l'espace de noms std, mais autant que je peux dire que la fusion de noms dans le code ci-dessous devrait être unique.Erreur de compilateur C++ ambiguë

Si je renommer la fusion en xmerge, tout fonctionne. Quel pourrait être le problème? D'où vient l'affrontement?

http://codepad.org/uAKciGy5

#include <iostream> 
#include <iterator> 
#include <vector> 

template<typename InputIterator1, 
     typename InputIterator2, 
     typename OutputIterator> 
void merge(const InputIterator1 begin1, const InputIterator1 end1, 
      const InputIterator2 begin2, const InputIterator2 end2, 
      OutputIterator out) 
{ 
    InputIterator1 itr1 = begin1; 
    InputIterator2 itr2 = begin2; 
    while ((itr1 != end1) && (itr2 != end2)) 
    { 
     if (*itr1 < *itr2) 
     *out = *itr1, ++itr1; 
     else 
     *out = *itr2, ++itr2; 
     ++out; 
    } 
    while (itr1 != end1) *out++ = *itr1++; 
    while (itr2 != end2) *out++ = *itr2++; 
} 

int main() 
{ 
    std::vector<int> l1; 
    std::vector<int> l2; 
    std::vector<int> merged_list; 

    merge(l1.begin(),l1.end(), 
     l2.begin(),l2.end(), 
     std::back_inserter(merged_list)); 

    return 0; 
} 
+0

Quel est le message d'erreur? Mon compilateur ne se plaint pas, il compile le code très bien. – Oswald

+0

Compile bien ici. (gcc 4.4.3) –

+3

Pourquoi devrais-je lui donner un nom différent? Je n'utilise pas d'espace de noms std. –

Répondre

16

compilateur se confondre entre votre fonction merge et la std::merge définie dans le algorithm. Utilisez ::merge pour enlever cette ambiguïté. Cet appel est ambigu lorsque le compilateur utilise Argument Dependendent Lookup pour rechercher la fonction lorsqu'un nom de fonction non qualifié est utilisé.

+1

C'est ce que je pense qui se passe mais cette routine ne devrait pas être dans l'espace de noms std? –

+7

@Reyzooti: Le problème est que Argument Dependent Lookup implique que puisque les types passés à l'appel de la fonction sont définis dans 'std', alors l'espace de noms' std' entre dans l'espace de recherche. Fondamentalement, c'est ce qui vous permet d'écrire 'std :: string (" Hi ") + std :: string (" là ")' en dehors de l'espace de noms 'std'. Le 'opérateur +' pour les chaînes est défini dans 'std', mais vous voulez sûrement que ce code fonctionne sans avoir à écrire' std :: operator + (str1, str2) 'ou' str1.opérateur + (str2) ', selon la façon dont l'opérateur est défini, ce dont je ne me soucie pas vraiment. –

+5

@Reyzooti: Oui, la version standard de 'merge' de la bibliothèque standard est dans l'espace de noms' std' - mais ADL le considère toujours comme candidat car les arguments de la fonction proviennent de l'espace de noms 'std' (pour plus de détails de comment fonctionne ADL voir l'article Wikipedia). –