I wish to send an integer to a function, that integer might be 8/16 bits depending on conditions. Can I declare one function to receive either int8/in16 as argument, depending on what the caller sends? Or, do I have to declare two functions one for each type (what I am doing at present)?
void func(uint8_t/uint16_t value)
or
void func(uint8_t value) void func(uint16_t value)
CodePudding user response:
This can be done by using function template and SFINAE as shown below:
#include <cstdint>
#include <iostream>
template <typename T> std::enable_if_t<std::is_same_v<T, uint8_t>> func(const T& t)
{
std::cout << "uint8 version called" <<std::endl;
}
template <typename T> std::enable_if_t<std::is_same_v<T, uint16_t>> func(const T& t)
{
std::cout << "uint16 version called" <<std::endl;
}
int main()
{
uint8_t x = 4;
func(x); //calls uint8 version
uint16_t y = 4;
func(y); //calls uint16_t version
}
CodePudding user response:
With C 20, we can use requires
clause instead of SFINAE to do the same:
#include <cstdint>
#include <iostream>
template <typename T> void func(const T& t) requires std::is_same_v<T, uint8_t>
{
std::cout << "uint8 version called" <<std::endl;
}
template <typename T> void func(const T& t) requires std::is_same_v<T, uint16_t>
{
std::cout << "uint16 version called" <<std::endl;
}
int main()
{
uint8_t x = 4;
func(x); //calls uint8 version
uint16_t y = 4;
func(y); //calls uint16_t version
}
CodePudding user response:
@Jason Liam is onto it, but if you want to different functions, standard overloading is the answer. If you want to use a single function for those two types, combine Jason's functions:
#include <cstdint>
#include <iostream>
#include <typeinfo>
template <typename T> void func(const T& t) requires
std::is_same_v<T, uint8_t> || std::is_same_v<T, uint16_t>
{
std::cout << "called with type " << typeid(T).name() <<std::endl;
}
int main()
{
uint8_t x = 4;
func(x); //calls uint8_t version
uint16_t y = 4;
func(y); //calls uint16_t version
int z = 6;
// func(z); compiler error, z is not right type
}