Yeah, I know that I should make an iterator, but I need this done fast and writing a proper iterator for anything related to VC++ is beyond frustrating. (This also goes for many other standard things and is buggering up my work load. :( )
So I wrote a for_each() algorithm to deal with the nastiness:
template <typename K, typename AK, typename V, typename AV>
void for_each(CMap<K, AK, V, AV>& container, std::function<void(AK, AV)> body)
{
POSITION pos = container.GetStartPosition();
while (pos != NULL)
{
AK key;
AV value;
// Get key and value
container .GetNextAssoc(pos, key, value);
body(key, value);
}
}
But apparently VC++ can't deduce AK and AV for the function template. Is this normal or is this yet another limitation of VC++?
Edit Here is the errors as requested:
1>d:\projects\clean\cv32\cvcustombuttoninfo.cpp(113): error C2784: 'void for_each(CMap<KEY,ARG_KEY,VALUE,ARG_VALUE> &,std::function<void(AK,AV)>)' : could not deduce template argument for 'std::function<void(AK,AV)>' from 'CCVCustomRibbonInfo::WriteFile::<lambda_0513c2955d2b7b0197efcf2b0ce9322b>'
1> d:\projects\clean\cv32\cvcustombuttoninfo.cpp(66) : see declaration of 'for_each'
This seems to also happen on gcc 4.9.0 with -std=c++11 parameter.
#include <functional>
template <typename T>
void fn(T t, std::function<void(T)>)
{
}
int main()
{
int i;
fn(i, [](int i){});
return 0;
}
And the g++ errors:
/tmp/gcc-explorer-compiler115110-34-1cr9oud/example.cpp: In function 'int main()':
11 : error: no matching function for call to 'fn(int&, main()::)'
fn(i, [](int i){});
^
11 : note: candidate is:
4 : note: template void fn(T, std::function)
void fn(T t, std::function<void(T)>)
^
4 : note: template argument deduction/substitution failed:
11 : note: 'main()::' is not derived from 'std::function'
fn(i, [](int i){});
^
Compilation failed
You should make an iterator:
Code is pure C++98 since I don't know which C++11 features are implemented by whichever version of Visual C++ you are using.
C++ lambdas don't have the same type as an
std::function
with the same signature. This is why the template argument deduction fails - it works with exact types, more or less. Conversions are not considered using template argument deduction. You don't want to use anstd::function
in your template argument. To force signature, you can check thatFunc
is convertible to anstd::function<void(AK, AV)>
.