Reputation: 105
I have the following code to demonstrate a function been called inside another function.
The below code works correctly:
#include <iostream>
int thirds()
{
return 6 + 1;
}
template <typename T, typename B>
int hello(T x, B y , int (*ptr)() ){
int first = x + 1;
int second = y + 1;
int third = (*ptr) (); ;
return first + second + third;
}
int add(){
int (*ptr)() = &thirds;
return hello(1,1, thirds);
}
int main()
{
std::cout<<add();
return 0;
}
Now I want to pass one number as a parameter from add function ie into thirds function (thirds(6)).
I am trying this way:
#include <iostream>
int thirds(int a){
return a + 1;
}
template <typename T, typename B>
int hello(T x, B y , int (*ptr)(int a)() ){
int first = x + 1;
int second = y + 1;
int third = (*ptr)(a) (); ;
return first + second + third;
}
int add(){
int (*ptr)() = &thirds;
return hello(1,1, thirds(6)); //from here pass a number
}
int main()
{
std::cout<<add();
return 0;
}
My expected output is:
11
But It is not working. Please can someone show me what I am doing wrong?
Upvotes: 7
Views: 14614
Reputation: 82531
thirds(6)
yields a prvalue of type int
. This cannot be converted to a function pointer. You need to pass 6
as separate parameter.
Note: The beauty of C++ here is that you don't actually need to know, what you're passing, as long as you're willing to use a parameter of a type specified as a template parameter. You don't even need to restrict the number of parameters the function can be used with. And you don't even need to bother with the function pointer syntax...
int thirds(int a) {
return a + 1;
}
long f(std::string const& x, int y)
{
return x.size() + y;
}
template <typename T, typename B, class Function, class ... Args>
auto hello(T x, B y, Function f, Args...args) // deduce the return type
{
int first = x + 1;
int second = y + 1;
int third = f(args...);
return first + second + third;
}
int main()
{
std::cout
<< hello(1, 2, thirds, 6) << '\n'
<< hello(1, 2, f, "hello world", 8) << '\n'
<< hello(1, 2, []() {return 3; }) << '\n'
;
return 0;
}
Btw: In practice you should probably use perfect forwarding, but I left this out in the code above make it a bit more beginner friendly.
Here's the version of the function I'd implement in practice:
template <typename T, typename B, class Function, class ... Args>
decltype(auto) hello(T&& x, B&& y, Function&& f, Args&&...args)
{
return (std::forward<T>(x) + 1)
+ (std::forward<B>(y) + 1)
+ std::forward<Function>(f)(std::forward<Args>(args)...);
}
Upvotes: 4
Reputation: 29456
add
to pass a value to hello
, to be passed to the function given by the pointer ptr
, you have to add a separate parameter.std::function
instead of old c style funtion pointers.A complete example:
#include <iostream>
#include <functional>
int thirds(int a)
{
return a + 1;
}
template <typename T, typename B>
//------------------------------------------------VVVVV-
int hello(T x, B y, std::function<int(int)> func, int a)
{
int first = x + 1;
int second = y + 1;
int third = func(a);
return first + second + third;
}
int add()
{
std::function<int(int)> myfunc = thirds;
return hello(1, 1, myfunc, 6);
}
int main()
{
std::cout << add();
return 0;
}
Output:
11
Note: another solution could be to use std::bind
to create a callable from thirds
and the argument 6
. But I think the solution above is more simple and straightforward.
Upvotes: 9
Reputation: 83
The code you posted does not seem to compile. Have you tried something like the following?
#include <stdio.h>
#include <iostream>
int thirds(int a){
return a + 1;
}
template <typename T, typename B>
int hello(T x, B y , int (*ptr)(int)){
int first = x + 1;
int second = y + 1;
int third = ptr(first);
return first + second + third;
}
int add(){
int (*ptr)(int) = &thirds;
return hello(1, 1, ptr); //from here pass a number
}
int main()
{
std::cout << add();
return 0;
}
In addition, I would suggest looking into std::function and lambdas.
Upvotes: 1