Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to receive a function parameter of any type in C++ and get the type of the passed variable inside the function?

Tags:

c++

I want to be able to receive any type for the argument of a function and inside the function to determine the given type and take action accordingly.

Pseudocode:

void myFunction(any argument)
{
   if(argument is int)
   {
      myFunctionInt(argument);
   }
   if(argument is string)
   {
      myFunctionString(argument);
   }
}

Thanks.

like image 978
anegru Avatar asked Jul 16 '19 09:07

anegru


People also ask

Can you pass a type as a parameter in C?

You don't actually pass a type to a function here, but create new code for every time you use it. To avoid doubt: ({...}) is a "statement expression", which is a GCC extension and not standard C.

How can you get the type of arguments passed to a function?

There are two ways to pass arguments to a function: by reference or by value. Modifying an argument that's passed by reference is reflected globally, but modifying an argument that's passed by value is reflected only inside the function.

What are functions How are functions declared and parameters passed to the functions?

How you divide up your code among different functions is up to you, but logically the division is such that each function performs a specific task. A function declaration tells the compiler about a function's name, return type, and parameters. A function definition provides the actual body of the function.


2 Answers

First of all you should take a look at simple function overloading which allows you to achieve that it in an oldschool fassion:

void my_function(int value) {
    std::cout << "int\n";
}

void my_function(std::string value) {
    std::cout << "string\n";
}

Though this has some downsides, as it takes quite some lines of code (a new function for each type!). You also need to specifically name the type (with all qualifiers), which may be undesirable.


To follow your pseudecode, when using C++17 you can use if-constexpr to choose the right branch at compile time.

This is great, because you are even allowed to say something like value.length() when inside the std::string branch! This isn't possible with an regular old if.

So how can you determine what type value is? std::is_same_v<T, U> allows to perform an comparison, yielding only true if T is exactly an U - int or std::string in this case:

#include <type_traits>
#include <string>
#include <iostream>

template<typename T>
void my_function(T value) {
    if constexpr (std::is_same_v<T, int>) {
        std::cout << "int\n";
    }
    else if constexpr (std::is_same_v<T, std::string>) {
        std::cout << "string\n";
    }
}

This is how it performs:

my_function(5); //-> prints out 'int'
my_function(std::string{ "hello" }); //-> prints out 'string'

However, std::is_same_v doesn't consider qualifiers. This is a problem, for example this won't print out anything:

my_function<const int>(5);

because const int is not the same as int. To get rid of const and any references & std::decay_t comes in handy:

template<typename T>
void my_function(T value) {
    if constexpr (std::is_same_v<std::decay_t<T>, int>) {
        std::cout << "int\n";
    }
    else if constexpr (std::is_same_v<std::decay_t<T>, std::string>) {
        std::cout << "string\n";
    }
}

which correctly works, as seen now:

my_function<const int>(5);
my_function<const std::string&>(std::string{ "hello" });
int
string
like image 81
Stack Danny Avatar answered Nov 14 '22 22:11

Stack Danny


Template the function and make overloads for the recessary types.

template <typename T>

void myFunction(T a){

     myFunction(a);    
}

void myFunction(int i)
{
}

void myFunction(std::string)
{
}
like image 37
SilverTear Avatar answered Nov 14 '22 23:11

SilverTear