How do I get the address of an overloaded function?

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

int  inc(int  i) { return ++i; }
void inc(int& i) { ++i; }

int main()
{
    // should print the address of function inc( int)
    std::cout << reinterpret_cast<long>( &inc); // ?

    // should print the address of inc(int&)
    std::cout << reinterpret_cast<long>( &inc); // ?
}
How would that know which version of that function you're referring to?

Check out this page: http://en.cppreference.com/w/cpp/language/overloaded_address
Thanks, but that page is a bit too much technically for my language skills :(
Could you say, how i need to fix my example code?
So far I've understand the page, I could define for every function address a function pointer.
1
2
int (*ptr_1) (int) = inc;
void (*ptr_2)(int&) = inc;


But i have several addresses to overloaded fuctions to pass as arguments to other functions. Is there no way, passing the addresses of overloaded functions directly, without having define for everything a pointer?
@gentlegui
I think that reinterpret_cast is much better then (....)(my_var). Its name is ugly and this emphases it out to the reader. In my example I need the cast, otherwise cout evaluates the addresses into a bool.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>

int  inc(int  i) {
  std::cout << "Called int inc(int i): i = " << i << std::endl;
  return ++i;
}
void inc(int& i) {
  std::cout << "Called void inc(int& i): i = " << i << std::endl;
  ++i;
}

//Takes a pointer to a function having a return type of void
//and taking a reference to an integer as an argument
void take_ptr( void(*ptr)(int&), int &arg_to_send )
{
  ptr(arg_to_send);
}

//Takes a pointer to a function having a return type of int
//and taking an integer as an argument
void take_other_ptr( int(*ptr)(int) )
{
  ptr(5);
}

int main()
{
  int i = 5;

  //Just pass the name of the function
  take_ptr(inc, i);
  take_other_ptr(inc);
}
As for why it gets printed as a boolean

The C++ standard states:
4.13 Boolean Conversions
A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a
prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false;
any other value is converted to true
I don't believe there is any general solution to this issue. Note that the two definitions in the OP are almost completely ambiguous and, as such, are useless as overloaded functions.

This would not compile:
1
2
3
4
5
6
7
8
9
10
#include <iostream>

int  inc(int  i) { return ++i; }
void inc(int& i) { ++i; }

int main()
{
    int j = 0;
    inc(j);
}


If you wish to be able to differentiate between functions, name them differently.

That's why the first function has a return value.
You are making that function useless if you call it that way.

This may come as a surprise to you, but return types play no part in overload resolution. Spread some more misinformation.

And, btw:
gentleguy wrote:
There is a way.
Do you intend to elaborate on that or let the troll rest?
Last edited on
@cire
cire wrote:
"If you wish to be able to differentiate between functions, name them differently."

I need this for the 'connect' function from the Qt libraries. Here i have to pass pointers to overloaded methods which belongs to the library interface. So i can't name them differently.
I need this for the 'connect' function from the Qt libraries. Here i have to pass pointers to overloaded methods which belongs to the library interface. So i can't name them differently.


Use a cast to differentiate. That won't help with the code in the OP though, as the functions are ambiguous.

[edit: example below.]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <functional>
#include <iostream>

void inc(int& i) { ++i; std::cout << "inc(int&)\n"; }
void inc(double& val) { ++val; std::cout << "inc(double&)\n"; }

int main()
{
    int i = 0;
    double j = 0;

    inc(i);
    inc(j);

    std::cout << (void*)static_cast<void(*)(double&)>(inc) << '\n';
    std::cout << (void*)static_cast<void(*)(int&)>(inc) << '\n';
}


Actually, it will work with the code in the OP, although the line above: inc(i); would need to be explicitly differentiated with a cast for the compiler.
Last edited on
How would such a cast look? I need for both methods passing an int.

connect( button, &QPushButton::clicked, signalMapper, &QSignalMapper::map);
See the edit in the post above. (minus the (void*) which is only there to force the output to be the address rather than a boolean.)
Last edited on
Thank you cire, that's a good solution :-)
gentleguy wrote:
And you already mentioned it.

This is entirely the same as the previous "solution" you mentioned. The pointer is just unnamed.

And of course, you have undefined behavior here as well. You seem to enjoy that sort of thing. X is not an appropriate format specifier for a pointer, and there should be an explicit cast to void*.


Seems like a good moment to address:
gentleguy wrote:
Why don't you use printf?

Because it's not type safe and prone to error, as you've illustrated.
> How do I get the address of an overloaded function?

Using a type alias would help.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>

int foo( int a ) { return a+a ; }
double foo( double a ) { return a+a ; }
template < typename T > T foo( const T& a ) { return a+a ; }

int main()
{
    using fn_int = int(int) ;
    using fn_dbl = double(double) ;
    using fn_str = std::string( const std::string& ) ;

    fn_int* fi = foo ; // address of int foo(int)
    fn_dbl* fd = foo ; // address of double foo(double)
    fn_str* fs = foo ; // instantiate std::string foo( const std::string& ), take its address

    std::cout << fi(5) << ' ' << fd(2.3) << ' ' << fs("abc") << '\n' ;
}
Topic archived. No new replies allowed.