sirven que punteros puntero parametros para operaciones los funciones estructura ejemplos datos con como cadenas aritmetica apuntadores c++ pointers return-value

c++ - que - punteros como parametros de funciones en c



¿Cuál es la forma correcta de devolver un tipo de ''Valor no válido'' en C++, sin el uso de punteros? (3)

A menudo utilizo -1 como el tipo de valor no válido al regresar de una función, donde la entrada produce un resultado incorrecto. Por ejemplo, escribir una función de indexación donde el índice está fuera de los límites, en lugar de lanzar una excepción, se puede devolver -1 . Pero cuando se escribe una función que tiene valores negativos como posibles tipos de retorno, esta técnica no funciona. ¿Cuál es la forma correcta de devolver un valor de tipo no válido en tales casos?

La técnica que utilizo principalmente es establecer que el tipo de retorno sea de tipo *int y devolver un puntero a NULL . Pero, eso requiere que todos los valores de retorno sean de tipo puntero, lo que parece una sobrecarga adicional para la función. ¿Hay un estándar aceptado para devolver valores en tales casos?


Aparte de la respuesta que proporcioné anteriormente, hay una solución muy limpia y de paso continuo (dado que no eres virtual):

template<typename Success, typename Failed> void parse( const std::string& str, Success s, Failed f ) { auto a = start_parse(str); if( a.problem() ) return f(); // you _might_ have an error code here s( finish_parse(str, a) ); }

Entonces puedes personalizar por:

  • Éxito:
    • [&i] (int i_) { i = i_; }
    • out(i) , where out(int& output_) devuelve la lambda anterior para output_
    • código real haciendo algo útil
    • función para continuar con
  • Ha fallado:
    • [&i]{ i = 0; } [&i]{ i = 0; } , `[& i] {i = nullopt; }, o cualquier otro valor predeterminado
    • [] { throw MyFavouriteException(); }
    • reintentar la lógica
    • std::terminate()
    • []{} si no te importa (o si estás 100% seguro de que tendrá éxito)

Puede parecer un poco detallado, pero en mi humilde opinión:

  • es trivial leer
  • Se puede imitar cualquier otro esquema, incluso si no hay un controlador predeterminado.
    • fácil de cambiar también
  • ''No pagas por lo que no usas'', seguramente se puede optimizar
  • Cada esquema es visible y aparente desde el código:
    • para el valor predeterminado, el llamante lo establece, no el destinatario de la llamada o global
    • std::optional<> y el valor predeterminado se manejan de la misma manera
    • Por excepción, la persona que llama sabe mejor qué tirar
    • Para ninguna acción, no tienes que buscar la implementación para saber esto
    • para std::terminate() , bueno, ya sabes qué esperar
    • Si ''hablas'' CPS, puedes continuar y guardar un if / catch / etc.

El único problema que veo son las listas de inicializadores de constructores. Tiene alguna idea sobre esto?


En el C ++ más reciente, sugeriría usar std::optional<> ; si aún no lo tiene, boost::optional<> .


Una opción sería permitir que su función tome un bool& como un parámetro de salida utilizado para indicar si el valor devuelto es válido.

int myFunc(bool& valid); // sets ''valid'' to true if result is usable, false otherwise

Los usuarios pueden hacer

bool valid = false; Int result = myFunc(valid); if (!valid) { // Handle error } // Use result

No es la solución más bonita, pero hace el trabajo.