C++ STL 101: Overload function causes build error
Trivial code that works if I do not overload myfunc.
void myfunc(int i)
{
std::cout << "calling myfunc with arg " << i << std::endl;
}
void myfunc(std::string s)
{
std::cout << "calling myfunc with arg " << s << std::endl;
}
void testalgos()
{
std::vector<int> v;
v.push_back(1);
v.push_back(2);
std::vector<std::string> s;
s.push_back("one");
s.push_back("two");
std::for_each( v.begin(), v.end(), myfunc);
std::for_each( s.begin(), s.end(), myfunc);
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "Hello World" << std::endl;
testalgos();
return 0;
}
The following build errors repeat for both for_each calls.
error C2914: 'std::for_each' : cannot deduce template argument a开发者_JS百科s function argument is ambiguous error C2784: '_Fn1 std::for_each(_InIt,_InIt,_Fn1)' : could not deduce template argument for '_InIt' from 'std::_Vector_iterator<_Ty,_Alloc>'.
It does work if I do not overload myfunc.Can someone explain what is happening here.
TIA
In that context the overloads can't be resolved by the compiler. std::for_each()
expects some arbitrary type F
for its functor, not some specific function type, thus the overloaded myFunc
is ambiguous here.
You can explicitly select which overload to use:
std::for_each( v.begin(), v.end(), (void (*)(int))myfunc);
std::for_each( s.begin(), s.end(), (void (*)(std::string))myfunc);
Alternatives (last two are from the comments):
typedef void (*IntFunc)(int);
std::for_each(/*...*/, (IntFunc)myfunc);
typedef void IntFunc(int);
std::for_each(/*...*/, static_cast<IntFunc*>(&myFunc));
// using identity (e.g. from boost or C++0x):
std::for_each(/*...*/, (identity<void(int)>::type*)myfunc);
Compiler cannot deduce type of functor. You could make your function template:
template<typename T> void myfunc(T);
template<> void myfunc(int i)
{
std::cout << "calling myfunc with arg " << i << std::endl;
}
template<> void myfunc(std::string s)
{
std::cout << "calling myfunc with arg " << s << std::endl;
}
Then use it as follows:
std::for_each( v.begin(), v.end(), myfunc<int>);
std::for_each( s.begin(), s.end(), myfunc<std::string>);
The compiler cannot deduce which to use, as both overloads would match the argument (which doesn't depend on the types of the iterator in any way) equally well.
Another option in addition to explicitly casting the argument to suitable pointer type might be here to use the std::ptr_fun
helper function to wrap it in a functor, and help the template deduction by giving (part of) it explicitly.
std::for_each( v.begin(), v.end(), std::ptr_fun<int>(myfunc));
std::for_each( s.begin(), s.end(), std::ptr_fun<std::string>(myfunc));
精彩评论