Extraño error del compilador g++ al usar mi propia función plus() ("std::plus no es una función")
Frecuentes
Visto 321 veces
4
Recibo un extraño error de compilación de g++.
Dice "std::plus is not a function
" para el siguiente código, aunque no estoy incluyendo <functional>
y no estoy usando std
donde ocurre el error.
Aquí está el código:
#include <iostream>
template<class T1, class T2, class T3>
struct MyStruct {
T1 t1; T2 t2; T3 t3;
MyStruct() {}
MyStruct(T1 const& t1_, T2 const& t2_, T3 const& t3_)
: t1(t1_), t2(t2_), t3(t3_) {}
};
template<class T1, class T2, class T3>
MyStruct<T1, T2, T3> plus(MyStruct<T1, T2, T3> const& x,
MyStruct<T1, T2, T3> const& y) {
// ...
}
int main() {
typedef MyStruct<int, double, std::string> Struct;
Struct x(2, 5.6, "bar");
Struct y(6, 4.1, "foo");
Struct result = plus(x, y);
}
Aquí está el error completo (ligeramente reformateado):
/usr/include/c++/4.2.1/bits/stl_function.h: In function 'int main()':
/usr/include/c++/4.2.1/bits/stl_function.h:134:
error: 'template<class _Tp> struct std::plus' is not a function,
plus3.cc:13: error:
conflict with 'template<class T1, class T2, class T3>
MyStruct<T1, T2, T3> plus(const MyStruct<T1, T2, T3>&,
const MyStruct<T1, T2, T3>&)'
plus3.cc:21: error: in call to 'plus'
¿Alguien sabe por qué es esto y cómo evitar el error? Realmente me gustaría llamar a la función plus
.
El error no ocurre cuando mi plus
función no tiene 3 argumentos de plantilla, lo que tiene sentido después de ver la definición de std::plus
:
template <class _Tp>
struct plus : public binary_function<_Tp, _Tp, _Tp>
Pero sigue siendo extraño porque std::plus
Ni siquiera debería saberse en ese momento.
ACTUALIZACIÓN:
En respuesta a algunas respuestas, pegaré un código ligeramente modificado que también da el error. Mi plus
la función está en namespace foo
aquí, y se llama desde el mismo espacio de nombres, por lo que no debería haber ninguna necesidad de calificarlo usando foo::
:
#include <string>
namespace foo {
template<class T1, class T2, class T3>
struct MyStruct {
T1 t1; T2 t2; T3 t3;
MyStruct() {}
MyStruct(T1 const& t1_, T2 const& t2_, T3 const& t3_)
: t1(t1_), t2(t2_), t3(t3_) {}
};
template<class T1, class T2, class T3>
MyStruct<T1, T2, T3> plus(MyStruct<T1, T2, T3> const& x,
MyStruct<T1, T2, T3> const& y) {
// ...
}
template<class T1, class T2, class T3>
MyStruct<T1, T2, T3> bar(MyStruct<T1, T2, T3> const& x,
MyStruct<T1, T2, T3> const& y) {
return plus(x, y);
}
} // end foo
int main() {
typedef foo::MyStruct<int, double, std::string> Struct;
Struct x(2, 5.6, "bar");
Struct y(6, 4.1, "foo");
Struct result = foo::bar(x, y);
}
3 Respuestas
5
Es porque std::plus no es una función.
Su función plus está en el espacio de nombres global, por lo que debe hacer
Struct result = ::plus(x, y);
La razón por la que está tratando de usar std::plus es porque no fue explícito en la versión de plus que quería, por lo que el compilador usó Búsqueda de Koenig que encuentra más a través de sus argumentos.
contestado el 22 de mayo de 12 a las 21:05
Gracias por tu respuesta. Sin embargo, todavía es un misterio para mí, porque todavía recibo el error si mi plus
está en su propio espacio de nombres, vea la ACTUALIZACIÓN que hice en mi publicación. Parece que necesitaría calificar el plus
llamar con foo::plus
aunque ya estoy en foo
espacio de nombres También los 2 argumentos para plus
tiene foo
espacio de nombres, no en std
espacio de nombres. - Frank
Hm, ¿y hay alguna manera de suprimir Koenig Lookup? - Señor lister
También Struct result = plus<int,double,std::string>(x, y);
obras. - martín york
Está bien, pero todavía no veo una razón por la que debería ser obligatorio. - Frank
@MrLister: Sí. Sea explícito sobre qué función/tipo desea. - martín york
0
No obtendrá este error si coloca su función en un espacio de nombres diferente. Para esto están los espacios de nombres: puede tener el mismo símbolo/firma en diferentes espacios de nombres sin causar colisiones.
contestado el 22 de mayo de 12 a las 21:05
0
Intente especificar el espacio de nombres para usted plus() explícitamente
Struct result = ::plus(x, y);
Esto ayuda con gcc y no te obliga a poner tu plus() en un espacio de nombres diferente.
Loki Astari cuenta el resto
contestado el 22 de mayo de 12 a las 21:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas c++ compiler-errors g++ or haz tu propia pregunta.
Esto se compila con gcc 4.5.1 (después de comentar la lista de inicializadores) - jrok
@jrok: Interesante, entonces tal vez sea un error de g ++. También probé con g ++ 4.4.4 y recibo el mismo error. - Frank
Recibo el mismo error aquí con g ++ 4.3.2, por lo que no es solo usted. Y cuando inserto
using namespace std;
solo por el gusto de hacerlo, solo entonces comienza a quejarse de quereference to ‘plus’ is ambiguous
. ¡Así que sí sabe eso, al menos! problema interesante Pero podría ser solo un simple error del compilador, como sugiere el comentario de jrok. - Mr ListerSu problema podría estar relacionado con esto: ¿Cuáles son las trampas de las ADL?. si abres encabezado de su implementación, verá que incluye
bits/stl_function.h
(probablemente usan std::less para el operador de cadena<) - jrokComo menciona jrok, en C ++ se permite que un encabezado estándar traiga cosas de otros encabezados estándar. Esto es diferente a C, donde no se permite que un encabezado traiga declaraciones de otros encabezados estándar. - Michael Burr