2011-02-02 33 views
7

No se puede compilar el siguiente fragmento de código. El error parece ser algún tipo de llamada ambigua a la rutina de combinación. Según tengo entendido, STL tiene una rutina de fusión que se encuentra en el espacio de nombres estándar, pero por lo que puedo decir, la combinación de nombres en el siguiente código debe ser única.Error del compilador de C++ ambiguo

Si cambio el nombre de fusión a xmerge, todo funciona. ¿Cuál podría ser el problema? ¿De dónde viene el nombre del choque?

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

¿Cuál es el mensaje de error? Mi compilador no se queja, compila el código muy bien. – Oswald

+0

Compila bien aquí. (gcc 4.4.3) –

+3

¿Por qué debería darle un nombre diferente? No estoy usando el espacio de nombres estándar. –

Respuesta

16

compilador es conseguir confundido entre su función y la mergestd::merge definido en el algorithm. Use ::merge para eliminar esta ambigüedad. Esta llamada es ambigua ya que el compilador usa Argument Dependendent Lookup para buscar la función cuando se usa un nombre de función no calificado.

+1

Eso es lo que creo que está sucediendo, pero ¿no debería ser esa rutina en el espacio de nombres estándar? –

+7

@Reyzooti: El problema es que Argument Dependent Lookup implica que, dado que los tipos pasados ​​a la llamada de función se definen en 'std', el espacio de nombre' std' ingresa al espacio de búsqueda. Básicamente esto es lo que le permite escribir 'std :: string (" Hi ") + std :: string (" there ")' fuera del espacio de nombres 'std'. El 'operador +' para cadenas está definido dentro de 'std', pero seguramente quiere que ese código funcione sin tener que escribir' std :: operator + (str1, str2) 'o' str1.operador + (str2) ', dependiendo de cómo esté definido el operador, lo que no me importa. –

+5

@Reyzooti: Sí, la versión de la biblioteca estándar de 'merge' está en el espacio de nombres' std', pero ADL aún hace que se considere como candidato porque los argumentos para la función provienen del espacio de nombres 'std' (para más detalles de cómo funciona ADL ver el artículo de Wikipedia). –

Cuestiones relacionadas