2010-08-03 16 views
5

Estoy tratando de escribir una gramática extensible usando funciones, pero no puedo encontrar la sintaxis correcta para aceptar una función de plantilla. Estoy usando Visual C++ 2008. Aceptará una variable del mismo tipo que la función de plantilla, o una función similar que no sea de plantilla, pero no la función de la plantilla en sí.Operador de sobrecarga << para aceptar una función de plantilla

de error 1 error C2679: binario '< <': ningún operador encontró que toma un operando de la derecha del tipo '-función sobrecargada' (o no hay conversión aceptable) (línea ***)

class Grammar { 
    friend Grammar operator << (const Grammar& lhs, const char* rhs) { 
     return lhs; // append rhs to grammar 
    } 
    template<typename T> 
    friend Grammar operator << (const Grammar& lhs, T (*rhs)()) { 
     return lhs; // append rhs() to grammar 
    } 
}; 

template<typename T> 
class ExpressionParticle { 
}; 

template<typename T> 
ExpressionParticle<T> Expression() ; 

ExpressionParticle<int> ExpressionInt(); 

int _tmain (int argc, _TCHAR *argv[]) 
{ 
    ExpressionParticle<int> (*p)(); 

    p = Expression<int>; 

    Grammar() << "p"; 
    Grammar() << p; 
    Grammar() << ExpressionInt; 
    Grammar() << Expression<int>; // *** 

¿Cuál es el tipo de Expression<int> si no es el tipo de p de arriba? ¿Cómo es su tipo diferente al tipo de ExpressionInt.

+0

Fwiw, esta compila con g ++ 4.4.1 –

Respuesta

3

Su código se ve bien para mí, y g ++ está bien con eso también. Esto parece ser una extraña falla de resolución de sobrecarga en Visual Studio. VS2005 parece tener el mismo problema. Una posible solución es (probado con VS2005):

template<class T> 
T id(T t) {return t; } 
int main() 
{ 
    ExpressionParticle<int> (*p)(); 

    p = Expression<int>; 

    Grammar() << "p"; 
    Grammar() << p; 
    Grammar() << ExpressionInt; 
    Grammar() << id(Expression<int>); // *** 
} 
0

cambiar esta situación:

class Grammar { 
    friend Grammar operator << (const Grammar& lhs, const char* rhs) { 
     return lhs; // append rhs to grammar 
    } 
    template<typename T> 
    friend Grammar operator << (const Grammar& lhs, T (*rhs)()) { 
     return lhs; // append rhs() to grammar 
    } 
}; 

a esto:

class Grammar { 
public: 
    Grammar& operator << (const char* rhs) { 
     return *this; // append rhs to grammar 
    } 
    template<typename T> 
    Grammar& operator << (const T &rhs) { 
     return *this; // append rhs() to grammar 
    } 
}; 
+0

'gramática() << Expresión ();' tiene un significado completamente diferente. –

+0

¡ah! ... mi mal ... no noté esa parte. Pero la forma en que sobrecargó el 'operador <<' fue incorrecta, IMO. Cambiaré eso ahora. –

+0

@Luther Lo siento ... pero wat es el significado completamente diferente de 'Expresión ();' ¿otra vez? Es una función de plantilla y la función debe llamarse como una función. ¿No es así? ¡Lo resolví en Visual Studio 2008 y lo compila! –

0

Como otra solución, que era capaz de conseguir que funcione en VS2010 mediante fundición. Usé el typedef por conveniencia. VS2008 probablemente funcionará de la misma manera.

int _tmain (int argc, _TCHAR *argv[]) 
{ 
    typedef ExpressionParticle<int> (*FCN)(); 

    ExpressionParticle<int> (*p)() = Expression<int>; 

    Grammar() << "p"; 
    Grammar() << p; 
    Grammar() << ExpressionInt; 
    Grammar() << static_cast<FCN>(Expression<int>); 
0

MSVC 2013 todavía contiene el mismo error, pero al menos ahora se puede utilizar el C++ 11 sintaxis de la plantilla alias de nuevo si vas con la solución de colada:

template <typename T> 
using Fptr = ExpressionParticle<T>(*)(); 

luego hacer el molde como esta:

Grammar() << Fptr<int>(Expression<int>) << endl; 
Cuestiones relacionadas