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.
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.
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.
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.
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
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)
{
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With