Function pointers to operators

Just curious. Question within code.

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

struct Int{ int x; };
int operator +( Int a, Int b ){ return a.x + b.x; }


int main()
{
   // Why can I do this for a user-defined type ...
   int (*f)( Int, Int ) = operator + ;
   Int a{ 3 };
   Int b{ 4 };
   cout << f( a, b ) << '\n';

   // ... but I can't do this for a built-in type ?
// int (*g)( int, int ) = operator + ;
// cout << g( 3, 4 ) << '\n';

}

Last edited on
You can think of your user-defined operator+ as a function where "operator+" is the function name.

1
2
int operator+( Int a, Int b ){ return a.x + b.x; }
int       add( Int a, Int b ){ return a.x + b.x; }

You can even call it as a regular function

1
2
3
4
Int a{ 3 };
Int b{ 4 };
cout << add(a, b) << '\n';
cout << operator+(a, b) << '\n';

If you declare it as member function you would instead have to call it as a member function.

1
2
3
4
5
6
7
8
9
10
11
12
struct Int
{
	int x; 
	int operator+(Int other) const { return x + other.x; }
	int       add(Int other) const { return x + other.x; }
};

...
Int a{ 3 };
Int b{ 4 };
cout << a.add(b) << '\n';
cout << a.operator+(b) << '\n';

For built-in types you don't have such a user-defined function so you can't use it as a function, at least that's how I think about it.
Last edited on
Thank-you, Peter.

Peter87 wrote:
For built-in types you don't have such a [user-defined] function

Does this mean that for built-in types there is no built-in function that carries out the addition operation in the same way as I would define for a user type? I'm curious, because with template programming I have hitherto defined functions for a general type T, irrespective of whether it were built-in or user-defined: I've seen no distinction ... until I get to these fundamental operators.
There are no functions involved in standard operations on built in types.

For example:
1
2
3
4
5
6
7
8
9
10
11
12
struct Int { int x ; };

Int& operator++( Int& i ) { ++i.x ; return i ; }

int main()
{
    Int a{4} ;
    ++a + ++a ; // no undefined behaviour here (functions, ergo indeterminately sequenced)

    int b{4} ;
    ++b + ++b ; // this is undefined behaviour (unsequenced modifications to b)
}


Standard function objects (eg. std::plus) provide uniform interfaces to common arithmetic and logical operators.
For instance:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <functional>

struct Int { int x ; };

Int operator+ ( Int i, Int j ) { return { i.x + j.x } ; }

std::ostream& operator<< ( std::ostream& stm, Int i )
{ return stm << i.x ; }

int main()
{
    const Int a{5}, b{6} ;
    const int c{5}, d{6} ;

    const auto plus = std::plus<>{} ;

    std::cout << plus(a,b) << '\n'
              << plus(c,d) << '\n' ;
}

Last edited on
Thank-you, @JLBorges

JLBorges wrote:
There are no functions involved in standard operations on built in types.

Is there anything analogous to my line
int (*g)( int, int ) = operator + ;?

I've been trying to use std::plus<int> from the <functional> header, but so far with no luck.


EDIT: sorry, I missed your edit @JLBorges.
Last edited on
std::plus<int> is a class, not a function, so you can't point to it using a function pointer.

If you are using C++11 (or later) you could use a lambda.

 
int (*g)(int, int) = [](int a, int b) { return a + b; };

If you can't, or don't want to, use a lambda you can still accomplish the same thing by defining a regular function.

1
2
3
4
5
6
7
8
9
int add(int a, int b)
{
	return a + b;
}

int main()
{
	int (*g)(int, int) = add;
}
Last edited on
Mmm, I had been doing that, @Peter. I was just hoping to circumvent it by using
operator +
rather than having to define another function, lambda or otherwise.

It seems that standard/built-in types don't work in the same way as I had been (mistakenly) expecting.

Thanks, anyway, @JLBorges and @Peter,
Does this mean that for built-in types there is no built-in function that carries out the addition operation in the same way as I would define for a user type?
Correct. The point is that the compiler needs to generate processor instruction at one point.

If

int operator+ ( int i, int j )

where allowed how could the compiler ever produce these processor instructions?
Thanks @coder777. A catch-22 situation indeed.
Last edited on
Topic archived. No new replies allowed.