Como detecto el tipo de dato introducido en la llamada de una funcion?

Iniciado por @XSStringManolo, 8 Junio 2019, 23:40 PM

0 Miembros y 1 Visitante están viendo este tema.

@XSStringManolo

Como puedo implementar en la funcion una distincion para saber si en la llamada a la funcion en main he puesto el int 97 o el char 'a' para que la funcion me saque por pantalla el numero 97 o la letra a?

Tal y como lo tengo, le puse un static_cast para sacar la letra a.
Pero quiero que si se busca el numero 97, me salga por pantalla el numero 97 no la letra a.
Como hago esta distincion para saber si en la llamada se está buscando la letra a o el numero 97?

Tal y como está ahora, si busco el numero 97 me dirá que ha encontrado la letra a.
Cuando yo lo que quiero es buscar si el numero 97 está en el array. Y si le quito el cast pues tendré el mismo problema al reves, buscaré la letra a, y me dirá que encontró el numero 97.

Código (cpp) [Seleccionar]
#include <iostream>
#include <array>
#include <algorithm>

using namespace std;
using MiArray = std::array<int, 10>;

MiArray primerArray = {0,1,2,3,4,5,'a',6,7,8};

void BuscarEnElArray(MiArray miArray, auto CosaAbuscar);

int main()
{
  BuscarEnElArray(primerArray, 'a');
  cin.get();

return 0;
}


void BuscarEnElArray(MiArray miArray, auto CosaAbuscar)
{
  MiArray::iterator found = find(miArray.begin(), miArray.end(), CosaAbuscar);
  if ( found != miArray.end() )
  {
       cout << "Encontrado: " << static_cast<char>(*found) <<endl;
  }
}


Me gustaría que fuese con un solo array para no tener que crear un array para cada tipo de dato distinto.

K-YreX

No sé muy bien lo que pretendes la verdad. Quiero decir no lo entiendo... Si el array es de tipo <int> aunque tú pongas 'a', internamente te estará guardando un <int>, es decir, 97 en este caso. Pero bueno, para que haga lo que tú quieres creo que podrías sobrecargar la función con ambos tipos <char/int> o pasar un string y comprobar si ese string es numérico o alfabético.
Hay un par de funciones de la librería <cctype> muy útiles para esto último que te he comentado que son <isalpha()> e <isnum()>.

Yo personalmente no veo muy recomendable usar <auto> para un parámetro porque entonces estás permitiendo pasar cualquier cosa. Por eso el tema de buscar un tipo de variable común <string> o hacer una sobrecarga para los casos que quieras permitir.

Otra opción que veo ahora sería usar un <template> pero para esto sería recomendable aplicárselo tanto al array como al parámetro a buscar.

No sé si te servirá alguna de las opciones pero nunca me ha dado por probar este tipo de "curiosidades". :-X
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

RayR

Las únicas soluciones son las que te dio YreX-DwX. Y ojo, que realmente no es válido usar auto en parámetros de funciones, ni siquiera en C++17. Algunos compiladores permiten cosas como ésa, pero no es estándar, por lo que no hay garantía de que siempre funcione. De todas formas en este caso no es relevante, ya que lo que determina el valor a imprimir es el tipo del array. Es decir, podrías cambiar auto por char, y seguiría sin hacer diferencia, ya que lo que estás imprimiendo es el valor apuntado por el iterador del array, que es de tipo int.

@XSStringManolo

#3
Creo que lo voy a hacer recorriendo el propio código fuente del main xD. Recorro el main.cpp y compruebo si hay alguna comilla simple entre los parentesis de la llamada a la funcion. Si los hay uso static_cast<char> si no lo hay, no uso el cast.
Es para que me ordene un array según lo que yo quiera.
Quiero que me ordene por ejemplo:
1, 2, 3, 97, 4, 5, a , 6...
Pero a la vez quiero que ese a sea tratado como un int 97 pero no orendado con el mismo criterio que el int 97.

Despues según el orden del array sabré si el 97 en realidad es una 'a' o es un int 97 segun si el indice del array es par o impar.
Por ejemplo el primer 97 está en el indice [3] y el segundo 97 está en el indice [6] por lo que según esa regla podría imprimir en pantalla "97a".

Es para un cifrado que estoy haciendo. Que cambia caracteres a int o char según le convenga. Los char los pasa a binario, y los int cambian varios bits de char.
El 1 cambiaría el primer bit empezando por la derecha del binario. El 2 cambiaría el primero y el segundo. El 3 los 3 bits de la derecha, el 97 cambiaría los 8 bits del char 12 veces más 1 vez el de la derecha. (Por cada vuelta del for, hace cambios distintos) el 5 cambiaria los 5 bits de la derecha, y como en el siguiente está el char a modificar, se queda así el número.
Se pasaría a buscar el siguiente char del array para hacer el mismo proceso. Se pasan a base 64 todos los char resultantes se toma el binario de cada char modificado se les aplican diversos operadores binarios y se obtiene una clave. Esa clave se mezcla con otra generada por un numero aleatorio de una serie pseudoalatoria que depende del numero de bits cambiados y se le aplica al texto a cifrar que ahora está en base64.

Para descifrar el contenido necesitas poder calcular todos los elementos de la serie pseudoaleatoria y comprobarlos uno por uno descifrando el texto para dar con el original.
Segun la seguridad del cifrado se aumenta o disminulle el numero de elementos de la serie.
Solo el que cifra tiene la clave.  Para descifrar usas la clave o descifras probando elementos de la serie.


Pd: busco una manera de hacer las pruebas sin tener andar escribiendo por consola. Directamente desde el código.

Loretz

También puedes usar un array de variants; en tu caso podría ser:

Código (cpp) [Seleccionar]
#include <iostream>
#include <array>
#include <algorithm>
#include <variant>

using namespace std;
using MiArray = std::array<std::variant<int, char>, 10>;

auto PrintMiArray = [](auto&& i)
{
    std::cout << "Encontrado: " << i << '\n';
};


template<typename T>
void BuscarEnElArray(MiArray miArray, T CosaAbuscar)
{
    MiArray::iterator found = find(miArray.begin(), miArray.end(), std::variant<int,char>(CosaAbuscar));
    if (found != miArray.end()) {
        std::visit(PrintMiArray, *found);
    }
    else {
        std::cout << CosaAbuscar << " no encontrado\n";
    }
}


MiArray primerArray = { 0,1,2,3,4,5,'a',6,7,8 };

int main()
{
    BuscarEnElArray(primerArray, 'a');
    return 0;
}



@XSStringManolo

Ohh, no sabía que existía variant ni union ni nada que se le parezca.
Gracias por el código! Aprendí muchas cosas gracias a buscar variant y encontrarme con una pagina super útil con muy buenos ejemplos. Ahora ando a ponerlas en práctica junto a tú código. Veo necesario compartir la página por si alguien se encuentra con tu ejemplo y al igual que yo no lo entiende. Muchas gracias!
https://www.bfilipek.com/2018/06/variant.html?m=1