I tried to implement a map operator based on the C++ operator ->*. The purpose of this operator was to elegantly map/transform zero terminated char* strings and wchar_t* strings inplace.
template<typename T> T* operator->*(T* iteratee, std::function<T(T)> mapFun) { for(T* it = iteratee; *it; ++it) *it = mapFun(*it); return iteratee; } using namespace std; int main() { char msg[] = "Hello World!"; cout << msg << endl; cout << msg->*([](char c ) { return c+1; }) << endl; } Desired output is:
Hello World! Ifmmp!Xpsme" But instead I only get the following error:
21:15: error: no match for 'operator->*' (operand types are 'char*' and 'main()::<lambda(char)>') 21:15: note: candidate is: 10:4: note: template<class T> T* operator->*(T*, std::function<T(T)>) 10:4: note: template argument deduction/substitution failed: 21:46: note: 'main()::<lambda(char)>' is not derived from 'std::function<T(T)>' Why is this happening?
I know, I can fix the Problem by either calling the operator explicitly, which makes the operator pretty inconvenient
cout << operator->*<char>(msg, [](char c ) { return c+1; }) << endl; or by adding a second template argument to the operator:
template<typename T, typename F> T* operator->*(T* iteratee, F mapFun) { for(T* it = iteratee; *it; ++it) *it = mapFun(*it); return iteratee; } But this it not optimal, because the compiler doesn't complain, when I pass a function of the wrong type like the following usage, which compiles without warning:
cout << msg->*([](int i) { return 'a'+i; }) << endl; So, how can I use the std::function-version of the operator without explicitly mentioning the template arguments?