I have the following code which compiles without any problem
#include<iostream>
#include<vector>
template<typename T>
void compare(const std::vector<T> &v1, const std::vector<T> &v2, void(*func)(const int&,const int&,const size_t&))
{
size_t minLen{v1.size() < v2.size() ? v1.size() : v2.size()};
for(size_t index{}; index<minLen; index++)
func(v1[index],v2[index],index);
}
template<typename T>
void matcher(const T& val1,const T& val2,const size_t& index)
{
if(val1==val2) std::cout<<"v1 and v2 are equal at index "<<index<<"\n";
}
int main()
{
std::vector v1={1,5,-9,-8};
std::vector v2={1,5,-9,-80,45};
compare(v1,v2,&(matcher<int>));
return 0;
}
Now I have the following question : Is compare(v1,v2,&(matcher<int>));
equivalent to compare(v1,v2,&matcher);
and why
An Edit
When I delete the const
before index
var in matcher, the compiler shows the following error
temp.cpp(85): error C2664: 'void compare1<int>(const std::vector<int,std::allocator<int>> &,const std::vector<int,std::allocator<int>> &,void (__cdecl *)(const int &,const int &,const size_t &))': cannot convert argument 3 from 'void (__cdecl *)(const T &,const T &,size_t &)' to 'void (__cdecl *)(const int &,const int &,const size_t &)'
temp.cpp(85): note: None of the functions with this name in scope match the target type
temp.cpp(64): note: see declaration of 'compare1'
The compiler says
'void (__cdecl *)(const T &,const T &,size_t &)' to 'void (__cdecl *)(const int &,const int &,const size_t &)'
It doesn't say
'void (__cdecl *)(const int &,const int &,size_t &)' to 'void (__cdecl *)(const int &,const int &,const size_t &)'
compare(v1,v2,&matcher);
works because of template argument deduction.
Template argument deduction is used when taking an address of a overload set, which includes function templates.
and
If the function name names a function template, then, first, template argument deduction is done, and if it succeeds, it produces a single template specialization which is added to the set of overloads to consider.
The 3rd function parameter type of compare
is void(*func)(const int&,const int&,const size_t&)
, when pass &matcher
, the template parameter T
of matcher
is deduced as int
, the effect is just same as specifying the template argument explicitly as matcher<int>
.
BTW: What kind of message get printed out depends on the implementation of compiler; e.g. clang gives different one.