Función estática de sobrecarga C ++ con función no estática

Me gustaría imprimir dos cosas diferentes dependiendo de si una función se llama estáticamente con Foo::print() o de una instancia de Foo foo; foo.print(); Foo foo; foo.print();

EDITAR: Aquí hay una definición de clase que definitivamente no funciona, como ya lo han respondido algunas personas.

 class Foo { string bla; Foo() { bla = "nonstatic"; } void print() { cout << bla << endl; } static void print() { cout << "static" << endl; } }; 

Sin embargo, ¿hay una buena forma de lograr este efecto? Básicamente, me gustaría hacer:

 if(this is a static call) do one thing else do another thing 

Expresado de otra manera, sé que PHP puede verificar si *this variable está definida o no para determinar si la función se llama estáticamente. ¿C ++ tiene la misma capacidad?

No, está directamente prohibido por la norma:

Norma ISO 14882: 2003 C ++ 13.1 / 2 – Declaraciones sobrecargables

Ciertas declaraciones de funciones no se pueden sobrecargar:

  • Las declaraciones de funciones que difieren solo en el tipo de devolución no pueden sobrecargarse.
  • Las declaraciones de función de miembro con el mismo nombre y los mismos tipos de parámetros no pueden sobrecargarse si alguna de ellas es una statement de función miembro static (9.4).

[Ejemplo:

 class X { static void f(); void f(); // ill-formed void f() const; // ill-formed void f() const volatile; // ill-formed void g(); void g() const; // OK: no static g void g() const volatile; // OK: no static g }; 

-Final ejemplo]

Además, sería ambiguo de todos modos, ya que es posible llamar funciones estáticas en instancias:

ISO 14882: 2003 C ++ Standard 9.4 / 2 – Miembros estáticos

Se puede hacer referencia a un miembro estático s de clase X utilizando la expresión de id. Calificada X::s ; no es necesario utilizar la syntax de acceso de los miembros de la clase (5.2.5) para referirse a un static member . Se puede hacer referencia a un miembro static utilizando la syntax de acceso de miembro de clase, en cuyo caso se evalúa la object-expression objeto. [Ejemplo:

 class process { public: static void reschedule(); } process& g(); void f() { process::reschedule(); // OK: no object necessary g().reschedule(); // g() is called } 

-Final ejemplo]

Entonces habría ambigüedad con lo que tienes:

 class Foo { public: string bla; Foo() { bla = "nonstatic"; } void print() { cout << bla << endl; } static void print() { cout << "static" << endl; } }; int main() { Foo f; // Call the static or non-static member function? // C++ standard 9.4/2 says that static member // functions are callable via this syntax. But // since there's also a non-static function named // "print()", it is ambiguous. f.print(); } 

Para abordar su pregunta sobre si puede verificar en qué instancia se está llamando a una función miembro, existe la palabra clave this . La palabra clave this apunta al objeto para el que se invocó la función. Sin embargo, la palabra clave this siempre apuntará a un objeto, es decir, nunca será NULL . Por lo tanto, no es posible verificar si una función se está llamando estáticamente o no a PHP.

ISO 14882: 2003 C ++ Standard 9.3.2 / 1 - El puntero este

En el cuerpo de una función miembro no estática (9.3), la palabra clave this es una expresión non-lvalue cuyo valor es la dirección del objeto para el que se llama a la función.

Definitivamente no está permitido. No veo ninguna forma limpia de lograr esto. ¿Cuál es exactamente el problema que quieres resolver de esta manera?

No puedes hacer eso exactamente, ver la respuesta de In silico .

Pero puedes hacer que Foo::print() y Foo foo; print(foo); Foo foo; print(foo); hacer cosas diferentes (Defina la void print(Foo& foo) en el mismo espacio de nombres como class Foo , se encontrará con ADL).

En cualquier caso, esta no es una buena idea. Usted tiene dos funciones muy similares en su nombre que hacen cosas completamente diferentes, lo cual viola los buenos principios de diseño.

La respuesta es no, porque no se puede sobrecargar en función de un tipo de devolución.

Ciertamente puede tener métodos estáticos en una clase, pero no puede tener:

 static void foo(); void foo(); 

Porque tienen la misma firma de método.

EDITAR: Vi tu comentario diciendo por qué querías hacer esto, y que querías acceder a las variables de los miembros. Deberías hacer esto:

 static void print(Foo f); void print(); .... static void Foo::print(Foo f) { int a = fa; // do something with a } 

(O crea getters y setters en Foo, etc., pero esa es la idea general)