Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determining which overload was selected

Let's say I have some arbitrary complicated overloaded function:

template <class T> void foo(T&& );
template <class T> void foo(T* );
void foo(int );

I want to know, for a given expression, which foo() gets called. For example, given some macro WHICH_OVERLOAD:

using T = WHICH_OVERLOAD(foo, 0);       // T is void(*)(int);
using U = WHICH_OVERLOAD(foo, "hello"); // U is void(*)(const char*);
// etc.

I don't know where I would use such a thing - I'm just curious if it's possible.

like image 515
Barry Avatar asked Feb 22 '16 18:02

Barry


People also ask

How can you tell overloaded methods apart?

Overloaded methods are differentiated by the number and the type of the arguments passed into the method. In the code sample, draw(String s) and draw(int i) are distinct and unique methods because they require different argument types.

Which type determines the overloaded method which will be used at the compile time?

Explanation: 1. Polymorphism, which works at compile-time, includes method overloading.

When you call an overloaded function How does compiler identify the right one?

At compile time, the compiler chooses which overload to use based on the types and number of arguments passed in by the caller. If you call print(42.0) , then the void print(double d) function is invoked. If you call print("hello world") , then the void print(std::string) overload is invoked.

What are the scenarios in which we can overload the function?

If any class has multiple functions with different parameters having the same name, they are said to be overloaded. If we have to perform a single operation with different numbers or types of arguments, we need to overload the function. If I say parameter list, it means the data type and sequence of the parameters.


1 Answers

Barry, sorry for the misunderstanding in my first answer. In the beginning I understood your question in a wrong way. 'T.C.' is right, that it is not possible except in some rare cases when your functions have different result types depending on the given arguments. In such cases you can even get the pointers of the functions.

#include <string>
#include <vector>
#include <iostream>

//template <class T> T foo(T ) { std::cout << "template" << std::endl; return {}; };
std::string foo(std::string) { std::cout << "string" << std::endl; return {}; };
std::vector<int> foo(std::vector<int>) { std::cout << "vector<int>" << std::endl; return {}; };
char foo(char) { std::cout << "char" << std::endl; return {}; };

template<typename T>
struct Temp
{
    using type = T (*) (T);
};

#define GET_OVERLOAD(func,param) static_cast<Temp<decltype(foo(param))>::type>(func);

int main(void)
{
    auto fPtr1 = GET_OVERLOAD(foo, 0);
    fPtr1({});

    auto fPtr2 = GET_OVERLOAD(foo, std::string{"hello"});
    fPtr2({});

    auto fPtr3 = GET_OVERLOAD(foo, std::initializer_list<char>{});
    fPtr3({});

    auto fPtr4 = GET_OVERLOAD(foo, std::vector<int>{});
    fPtr4({});

    auto fPtr5 = GET_OVERLOAD(foo, std::initializer_list<int>{});
    fPtr5({});

    return 0;
}

The output is:

char
string
string
vector<int>
vector<int>
like image 65
Stamen Rakov Avatar answered Nov 07 '22 20:11

Stamen Rakov