Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading a function using templates

I am trying to define a function using templates and I want the typename to be either int or anEnum (a specific enum I had defined). I have tried the following but I have failed:

template <int | anEnum T> // or <int T, anEnum T> or <int, anEnum T> bool isFunction(const T &aVariable){} 

What I am trying to do is to use templates, instead of defining two overloaded functions. I'd prefer the function to be called as the following, without the programmer having to consider the type

isFunction(aVariable) // and not isFunction<int> (aVariable) nor isFunction<anEnum> (aVariable) 

Basically, I want this function to be templated for int and aNum types. I have searched for this, but could not find the answer. What may I be missing? Thank you,

like image 492
b.g. Avatar asked Feb 17 '20 09:02

b.g.


People also ask

Can you overload a template function?

You may overload a function template either by a non-template function or by another function template. The function call f(1, 2) could match the argument types of both the template function and the non-template function.

Can templates be used for functions?

Templates Specialization is defined as a mechanism that allows any programmer to use types as parameters for a class or a function. A function/class defined using the template is called a generic function/class, and the ability to use and create generic functions/classes is one of the critical features of C++.

What is the relationship between function templates and overloading?

overloading is used when we have various functions , doing SIMILAR operations . template is used when we have various functions , doing IDENTICAL operations .

How do you overload a function?

You overload a function name f by declaring more than one function with the name f in the same scope. The declarations of f must differ from each other by the types and/or the number of arguments in the argument list.


2 Answers

In addition to non-C++20 answer, if you are, by any chance, able to use C++20 and its concepts feature, I would suggest you the following implementation:

#include <iostream> #include <concepts>  enum class MyEnum {     A,     B,     C };  template <typename T> concept IntegralOrEnum = std::same_as<MyEnum, T> || std::integral<T>;  template <IntegralOrEnum T> bool isFunction(T const& aVariable) {     return true; }  int main() {     isFunction(MyEnum::A);     isFunction(3);     isFunction("my_string"); // error     return 0; } 

Demo

UPDATE

According to @RichardSmith's comment, here is a more scalable and reusable approach:

template <typename T, typename ...U> concept one_of = (std::is_same_v<T, U> || ...);  template <one_of<int, MyEnum> T> bool isFunction(T const& aVariable) {     return true; } 
like image 115
NutCracker Avatar answered Sep 19 '22 23:09

NutCracker


There are a couple of ways to accomplish this. All involve using the type_traits header. You can static assert on the types in question in the body of the function, for instance.

Or, if you need to consider this function among other overloads, a SFINAE technique can be employed.

template<typename T> auto isFunction(const T &aVariable)    -> std::enable_if_t<std::is_same<T, int>::value || std::is_same<T,anEnum>::value, bool> { } 

This will remove the function from an overload set before it's called if the types don't match. But if you don't need this behavior, a static assertion does allow for a more programmer friendly error message.

like image 35
StoryTeller - Unslander Monica Avatar answered Sep 19 '22 23:09

StoryTeller - Unslander Monica