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 are repeated for both for_each calls.

error C2914: 'std :: for_each': cannot output the template argument, because the function argument is ambiguous error C2784: '_Fn1 std :: for_each (_InIt, _InIt, _Fn1)': could not derive the template argument for '_InIt' from 'std :: _ Vector_iterator <_Ty, _Alloc> '.

It works if I do not overload myfunc.Can someone explains what is going on here.

TIA

+4
source share
3 answers

In this context, overloads cannot be resolved by the compiler. std::for_each() expects some arbitrary type F for its functor, and not some specific type of function, so the overloaded myFunc is ambiguous here.

You can explicitly choose 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 of comments):

 typedef void (*IntFunc)(int); std::for_each(/*...*/, (IntFunc)myfunc); typedef void IntFunc(int); std::for_each(/*...*/, static_cast<IntFunc*>(&myFunc)); // using identity (eg from boost or C++0x): std::for_each(/*...*/, (identity<void(int)>::type*)myfunc); 
+10
source

The compiler cannot infer the type of functor. You can create your own 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>); 
+4
source

The compiler cannot determine what to use, since both overloads will match the argument (which does not depend on the iterator types in any way) equally well.

Another option, in addition to explicitly casting the argument to the appropriate pointer type, may be here to use the helper function std::ptr_fun to wrap it in a functor and help to subtract the template by explicitly specifying it (part).

 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)); 
+2
source

Source: https://habr.com/ru/post/1308478/


All Articles