2

Consider this for a second:

template <class T_arr, class T_func>
void iter(T_arr *arr, int len, T_func func)
{
    for(int i = 0; i < len; i++)
    {
        func(arr[i]);
    }
}

void display(int a) {
    std::cout << "Hello, your number is: " << a << std::endl;
}

int main(void)
{    
    int arr[] = {1, 2, 3};

    iter(arr, 3, display);
    return (0);
}

Which works as expected, however, if I try to change the display function to a template:

template <class T>
void display(T a) {
    std::cout << "Hello, your number is: " << a << std::endl;
}

It stops working and i get this error: candidate template ignored: couldn't infer template argument 'T_func'.

How to make sense of this?

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
kuk
  • 127
  • 1
  • 8
  • 1
    When you call `iter(arr1, 3, display);`, _which_ `display` do you mean? `display`? `display`? `display`? The compiler is not able to figure out that "Oh, `T_func` is supposed to accept a `T_arr` as its argument, so because I've deduced `T_arr = int` I'll try instantiating `double` for `T_func`. – Nathan Pierson Dec 23 '21 at 00:33

1 Answers1

2

You need to specify the template argument for display explicitly:

iter(arr, 3, display<int>);

Or make iter taking function pointer:

template <class T_arr>
void iter(T_arr *arr, int len, void (*func)(T_arr))
{
    for(int i = 0; i < len; i++)
    {
        func(arr[i]);
    }
}

then you can

iter(arr, 3, display); // template argument gets deduced as int
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • 2
    The deduction part by specifying the signature is great! With `template void iter(T_arr *arr, int len, void (*func)(T_arr) = display)` it would even work as a default (if the `display` template has been defined before) and could be called with `iter(arr, 3);` – Ted Lyngmo Dec 23 '21 at 00:44