Home > Back-end >  Can a C function receive two types in one argument alternatively?
Can a C function receive two types in one argument alternatively?

Time:02-02

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
}

Test in compiler explorer

  • Related