2

I cannot use C++11.

Normally when using std::for_each with a member function, the provided data structure gives the object on which the bound member function is called. However, I would like to know if it's possible to provide my own object which is constant throughout the loop, and use the data structure for the parameters to this member function.

Here is an example of what I want to do.

std::string GenerateKey(const std::vector<std::string>& parameters)
{
    std::string key;
    key.reserve(std::accumulate(parameters.begin(), parameters.end(), 0, std::mem_fun_ref(&std::string::length)));
    std::for_each(parameters.begin(), parameters.end(), std::bind1st(std::mem_fun_ref(&std::string::append), key));
    return key;
}

The intention is that for each string in parameters, append will be called on key, and be passed a string from parameters.

Why does this std::for_each not work, and how or can it be made to work?

I know there are alternative ways to concatenate strings. I want to understand C++ functional programming better.

Thanks.

Here are error messages from VS2013, which I doubt will help..

generator.cpp(28): error C2784: 'std::const_mem_fun1_ref_t<_Result,_Ty,_Arg> std::mem_fun_ref(_Result (__thiscall _Ty::* )(_Arg) const)' : could not deduce template argument for 'overloaded function type' from 'overloaded function type'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(910) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(910) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(910) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(910) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(910) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(910) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(910) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(910) : see declaration of 'std::mem_fun_ref'
generator.cpp(28): error C2783: 'std::const_mem_fun1_ref_t<_Result,_Ty,_Arg> std::mem_fun_ref(_Result (__thiscall _Ty::* )(_Arg) const)' : could not deduce template argument for '_Result'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(910) : see declaration of 'std::mem_fun_ref'
generator.cpp(28): error C2783: 'std::const_mem_fun1_ref_t<_Result,_Ty,_Arg> std::mem_fun_ref(_Result (__thiscall _Ty::* )(_Arg) const)' : could not deduce template argument for '_Ty'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(910) : see declaration of 'std::mem_fun_ref'
generator.cpp(28): error C2783: 'std::const_mem_fun1_ref_t<_Result,_Ty,_Arg> std::mem_fun_ref(_Result (__thiscall _Ty::* )(_Arg) const)' : could not deduce template argument for '_Arg'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(910) : see declaration of 'std::mem_fun_ref'
generator.cpp(28): error C2784: 'std::const_mem_fun_ref_t<_Result,_Ty> std::mem_fun_ref(_Result (__thiscall _Ty::* )(void) const)' : could not deduce template argument for 'overloaded function type' from 'overloaded function type'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(901) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(901) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(901) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(901) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(901) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(901) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(901) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(901) : see declaration of 'std::mem_fun_ref'
generator.cpp(28): error C2783: 'std::const_mem_fun_ref_t<_Result,_Ty> std::mem_fun_ref(_Result (__thiscall _Ty::* )(void) const)' : could not deduce template argument for '_Result'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(901) : see declaration of 'std::mem_fun_ref'
generator.cpp(28): error C2783: 'std::const_mem_fun_ref_t<_Result,_Ty> std::mem_fun_ref(_Result (__thiscall _Ty::* )(void) const)' : could not deduce template argument for '_Ty'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(901) : see declaration of 'std::mem_fun_ref'
generator.cpp(28): error C2784: 'std::mem_fun1_ref_t<_Result,_Ty,_Arg> std::mem_fun_ref(_Result (__thiscall _Ty::* )(_Arg))' : could not deduce template argument for 'overloaded function type' from 'overloaded function type'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(893) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(893) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(893) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(893) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(893) : see declaration of 'std::mem_fun_ref'
generator.cpp(28): error C2914: 'std::mem_fun_ref' : cannot deduce template argument as function argument is ambiguous
generator.cpp(28): error C2783: 'std::mem_fun1_ref_t<_Result,_Ty,_Arg> std::mem_fun_ref(_Result (__thiscall _Ty::* )(_Arg))' : could not deduce template argument for '_Result'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(893) : see declaration of 'std::mem_fun_ref'
generator.cpp(28): error C2783: 'std::mem_fun1_ref_t<_Result,_Ty,_Arg> std::mem_fun_ref(_Result (__thiscall _Ty::* )(_Arg))' : could not deduce template argument for '_Ty'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(893) : see declaration of 'std::mem_fun_ref'
generator.cpp(28): error C2783: 'std::mem_fun1_ref_t<_Result,_Ty,_Arg> std::mem_fun_ref(_Result (__thiscall _Ty::* )(_Arg))' : could not deduce template argument for '_Arg'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(893) : see declaration of 'std::mem_fun_ref'
generator.cpp(28): error C2784: 'std::mem_fun_ref_t<_Result,_Ty> std::mem_fun_ref(_Result (__thiscall _Ty::* )(void))' : could not deduce template argument for 'overloaded function type' from 'overloaded function type'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(884) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(884) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(884) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(884) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(884) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(884) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(884) : see declaration of 'std::mem_fun_ref'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(884) : see declaration of 'std::mem_fun_ref'
generator.cpp(28): error C2783: 'std::mem_fun_ref_t<_Result,_Ty> std::mem_fun_ref(_Result (__thiscall _Ty::* )(void))' : could not deduce template argument for '_Result'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(884) : see declaration of 'std::mem_fun_ref'
generator.cpp(28): error C2783: 'std::mem_fun_ref_t<_Result,_Ty> std::mem_fun_ref(_Result (__thiscall _Ty::* )(void))' : could not deduce template argument for '_Ty'
          c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(884) : see declaration of 'std::mem_fun_ref'
generator.cpp(28): error C2780: '_Fn1 std::for_each(_InIt,_InIt,_Fn1)' : expects 3 arguments - 2 provided
          c:\program files\microsoft visual studio 12.0\vc\include\algorithm(29) : see declaration of 'std::for_each'
Neil Kirk
  • 21,327
  • 9
  • 53
  • 91

2 Answers2

1

std::string::append is overloaded and the compiler is unable to know which function you meant.

So, std::string::append actually refers to a set of functions.

P0W
  • 46,614
  • 9
  • 72
  • 119
0

This error there because there are some of overloaded versions function std::string::append, you can use cast to tell compiler what exacly function need to use:

std::for_each(parameters.begin(), parameters.end(), std::bind1st(std::mem_fun_ref(static_cast<std::string& (std::string::*)(const std::string&)>(&std::string::append)), key));

Edit: but in this case it won't be worked, because bind1st will not work with functions, that takes references as parameter. See: Using bind1st for a method that takes argument by reference

Community
  • 1
  • 1
user1837009
  • 485
  • 4
  • 11
  • I don't think compiler is happy again – P0W Aug 15 '13 at 12:34
  • `c:\program files\microsoft visual studio 12.0\vc\include\xfunctional(465): error C2535: 'std::basic_string,std::allocator> &std::binder1st,std::allocator>,const std::string &>>::operator ()(const std::basic_string,std::allocator> &) const' : member function already defined or declared` – Neil Kirk Aug 15 '13 at 12:36
  • @NeilKirk I edit my answer, there is another error by different cause and I don't know what better solution in this case. – user1837009 Aug 15 '13 at 13:01