2

I am calling a template based function which shares a type between a function and structure. What is wrong with this code? why do I receive error when I compile it?

test.cpp

#include <functional>
#include <iostream>

template<typename T>
struct mystruct
{
    T variable;
};

int myfunc(int x)
{
    return 2*x;
}

template<typename T>
T calculate(
    mystruct<T> custom_struct,
    std::function<T(T)> custom_func)
{
    return custom_func(custom_struct.variable);
}

int main()
{
    mystruct<int> A;
    A.variable=6;
    std::cout<<calculate(A,myfunc)<<std::endl;
    return 0;
}

Compiler results:

test.cpp:25:31: error: no matching function for call to ‘calculate(mystruct<int>&, int (&)(int))’
  std::cout<<calculate(A,myfunc)<<std::endl;
                               ^

4 Answers 4

7

There is no reason to use the std::function wrapper. Instead use a general template parameter F

template<typename T, class F>
T calculate(
    mystruct<T> custom_struct,
    F custom_func)
{
    return custom_func(custom_struct.variable);
}

Live Example

Note that you also forgot to access the variable member at the call site. Since you are doing generic programming here, you also want the return type to be equal to T, or even auto (C++14, for C++11 you want probably use decltype but that is too much repetition).

Sign up to request clarification or add additional context in comments.

1 Comment

I would also fix the int return type
3

Your code is a bit messy, but theres always a solution.

#include <functional>
#include <iostream>

template<typename T>
struct mystruct
{
    T variable;
};

const int myfunc(const int & x)
{
    return 2*x;
}

template<typename T>
T calculate(
    mystruct<T> custom_struct,
    std::function<T(T)> custom_func)
{
    return custom_func(custom_struct.variable);
}

int main()
{
    mystruct<int> A;
    A.variable=6;
    std::cout<<calculate<int>(A,myfunc)<<std::endl;
    return 0;
}

There was just a problem with return custom_func(custom_struct), you've to pass the variable member from that struct and add calculate<int> instead of calculate.

You can try/test the new code here: http://cpp.sh/33cpn

Comments

2
template<typename T>
int calculate(
    mystruct<T> custom_struct,
    std::function<T(T)> custom_func);

The compiler will attempt to deduce T from std::function<T(T)> as well as mystruct<T>, but deduction from the function pointer fails. One solution would be to disable template deduction on std::function<T(T)> by making it a non-deduced context:

template <typename T> struct identity { using type = T; };
template <typename T> using identity_t = typename identity<T>::type; 

template<typename T>
int calculate(
    mystruct<T> custom_struct,
    identity_t<std::function<T(T)>> custom_func)
{
    return custom_func(custom_struct.variable);
}

Although it makes the function signature a bit uglier, you can still have T deduced, so you can just call calculate(A,myfunc) rather than calculate<int>(A,myfunc).

However, in this situation you should use TemplateRex's solution as std::function comes with a bunch of overhead which you don't actually need unless you're wanting to store it somewhere.

Comments

1

You are wrongly passing custom_struct to custom_func in calculate().

Try passing custom_struct.variable instead:

template<typename T>
int calculate(
    mystruct<T> custom_struct,
    std::function<T(T)> custom_func)
{
    return custom_func(custom_struct.variable);
}

Also on ideone

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.