Why can't the compiler infer the template arguments?
I tried to implement a C ++ based map operator operator ->*
. The purpose of this statement was to elegantly display / convert null terminated strings char*
and wchar_t*
inplace strings.
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:
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 explicitly calling the operator, which makes the operator rather awkward
cout << operator->*<char>(msg, [](char c ) { return c+1; }) << endl;
or by adding a second template argument to the statement:
template<typename T, typename F>
T* operator->*(T* iteratee, F mapFun) {
for(T* it = iteratee; *it; ++it)
*it = mapFun(*it);
return iteratee;
}
But this is 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 an operator without explicitly mentioning template arguments?
source to share
No one has answered this question yet
See similar questions:
or similar: