pointer to function not working.

Trying to pass the pointer from getArithmeticFunction(op) to appropriate functions above. Want to pair the character to a function access.(I have cut out the guard against the wrong input for now). What's wrong here?

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
34
35
36
37
38
39
40
41
42
43
44
45
46

#include<iostream>

int add(int x, int y)
{
	return x + y;
}

int subtract(int x, int y)
{
	return x - y;

}

int multiply(int x, int y)
{
	return x * y;
}

int divide (int x, int y)
{
	return x/y;
}

int * getArithmeticFunction(char op)
{
	switch(op)
	{
	case '+' : return &add;
	case '-' : return &subtract;
	case '/' : return &divide;
	case '*' : return &multiply;
	}
}

int main()
{
	char op;
	std::cout<<"input operator :";
	std::cin>>op;

	int * function_select = getArithmeticFunction(op);


	return 0;
}


compile erors:

..\src\main.cpp:28:21: error: cannot convert 'int (*)(int, int)' to 'int*' in return
  case '+' : return &add;
                     ^
..\src\main.cpp:29:21: error: cannot convert 'int (*)(int, int)' to 'int*' in return
  case '-' : return &subtract;
                     ^
..\src\main.cpp:30:21: error: cannot convert 'int (*)(int, int)' to 'int*' in return
  case '/' : return &divide;
                     ^
..\src\main.cpp:31:21: error: cannot convert 'int (*)(int, int)' to 'int*' in return
  case '*' : return &multiply;
Last edited on
Your function int * getArithmeticFunction(char op) says it returns an object of type pointer-to-int, but you're trying to make it return an object of type int (*)(int, int) (i.e. a pointer-to-a-function-that-accepts-two-int-paramters-and-returns-an-int-pointer).

You need to make what it says it returns match what it does return.

This being C++, you should prefer proper function objects to function pointers.

Alternatively, have C++ do the matching of types for you:

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
34
35
36
37
38
39
40
41
42
43
44
45
#include<iostream>

int add(int x, int y)
{
	return x + y;
}

int subtract(int x, int y)
{
	return x - y;

}

int multiply(int x, int y)
{
	return x * y;
}

int divide (int x, int y)
{
	return x/y;
}

auto getArithmeticFunction(char op)
{
	switch(op)
	{
	case '+' : return &add;
	case '-' : return &subtract;
	case '/' : return &divide;
	case '*' : return &multiply;
	}
}

int main()
{
	char op;
	std::cout<<"input operator :";
	std::cin>>op;

	auto func = getArithmeticFunction(op);
	std::cout << func(10,5) << std::endl;

	return 0;
}
Last edited on
getting this compile error:
..\src\main.cpp:24:35: error: 'getArithmeticFunction' function uses 'auto' type specifier without trailing return type
 auto getArithmeticFunction(char op)


If feels "like cheating" with auto. Is there any way to output the type the auto keyword settled on?

e.g. auto getArithmeticFunction(char op)
What type did compiler use?
Last edited on
Compiling with -std=c++1y will remove that compiler error, at least in eclipse ide:

So I need an answer that won't require changing ide props all the time...

Unless that is a parent setting to -std=c++11
Last edited on
You should definitely consider using modern C++ as standard. It's there for a reason. -std=c++1y is (I guess, depending on what compiler you're using) a superset of c++11. Unless you've got a reason not to, I'd suggest just always using the most recent C++ standard your compiler supports.

gcc 6.1 came out just a couple of weeks ago. It's nice, and it uses C++14 as standard (so you won't need any -std=xx switch). https://gcc.gnu.org/ml/gcc-announce/2016/msg00000.html

Answering your question; you can get the exact type with decltype. It's a bit ugly and fiddly, so I use the boost library to make it easy and pretty:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <boost/type_index.hpp>

using namespace std;
using namespace boost::typeindex;

int add(int x, int y)
{
	return x + y;
}

int subtract(int x, int y)
{
	return x - y;

}

int multiply(int x, int y)
{
	return x * y;
}

int divide (int x, int y)
{
	return x/y;
}

auto getArithmeticFunction(char op)
{
	switch(op)
	{
	case '+' : return &add;
	case '-' : return &subtract;
	case '/' : return &divide;
	case '*' : return &multiply;
	}
}

int main()
{
	char op;
	std::cout<<"input operator :";
	std::cin>>op;

	auto func = getArithmeticFunction(op);
	cout << type_id_with_cvr<decltype(func)>().pretty_name() << '\n';
	std::cout << func(10,5) << std::endl;

	return 0;
}




I understand why it feels like "cheating", and I definitely not an advocate of "auto everywhere" but there are times and places where the cost of deducing and typing and subsequently reading the exact type are outweighed by an auto.

Your options are for you to laboriously exactly work out the return type, and type it in everywhere it's needed (which will be a pain to read and prone to error and draws attention away from the actual meaning), or to just use auto, which doesn't mean "any type"; it still means "the appropriate, exact, fixed type".

At risk of sliding into off-topic, code is written both for the compiler to read and for the programmer (who may not be the person who wrote it originally) to understand.

A big clunky pointer-to-function-type is error-prone and hard to read; a C++ function object is clearly a function and can be passed around as an object, so it's easier to understand and easier to work with (so better on all counts) ; "auto" in this case allows one to express the idea that you don't care about the exact return type, which is some kind of horrific function pointer - the point of it isn't the type, but the meaning. The meaning is that it's a function.

I would suggest that you definitely do not work with function pointers; I think that a proper C++ function object is what you're looking for, as that maintains the readable type information but is also a lot easier and more useful and less error-prone and more maintainable than function pointers.

Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using fn_type = int(int,int) ; // fn_type is the type of the function

fn_type* getArithmeticFunction(char op) // return 'pointer to fn_type'
{
	switch(op)
	{
        case '+' : return &add;
        case '-' : return &subtract;
        case '/' : return &divide;
        case '*' : return &multiply;
        default: return nullptr ; // **** avoid undefined behaviour
	}
}

decltype(&add) getArithmeticFunction(char op) ; // same as above 
Oh yes, that too. A grown-up typedef. Good spot.
code is written both for the compiler to read and for the programmer (who may not be the person who wrote it originally) to understand.


Hey guys - of course I am the original writer! For better or worse: )
Topic archived. No new replies allowed.