Q:

Failure to Match Template Using Function Pointer as Argument

I am attempting to write a function which will operate on a std::map of any key and class pointer given to it, and create a new std::map with an index based on the return value of a function in the class. Essentially, a template function to re-index a map based on a function in its contained class. However, I am having compiler errors when trying to invoke the function.
template<class AnyType, class ValueType, class FunctionType>
AssocArray<FunctionType,ValueType> reindex( const AssocArray<AnyType, ValueType>& original, FunctionType (*getterFunction)() ) {
    AssocArray<FunctionType, ValueType> ret;
    FunctionType index;
    for(typename AssocArray<AnyType,ValueType>::const_iterator it = original.begin(); it!=original.end(); it++) {
        index = ((*it->second).*getterFunction)();
        ret[index] = it->second;
    }
    return ret;
}

Invoked by:
floatIndexed = reindex( intIndexed, &test::getB );

Where getB is of float type.
This results in the compiler error:
src/World.cpp:78:50: error: no matching function for call to ‘reindex(std::map<int, onathacar::test*>&, float (onathacar::test::*)())’
src/World.cpp:78:50: note: candidate is:
./include/Types.h:123:36: note: template<class AnyType, class ValueType, class FunctionType> std::map<PreservedType, ValueType> onathacar::reindex(const std::map<LookupType, ValueType>&, FunctionType (*)())

I have tried different variations of this, including using "FunctionType (ValueType::*getterFunction)()" and changing "AssocArray" to "AssocArray". The only one which worked added a fourth template argument:
template<class AnyType, class ValueType, class FunctionType, class SomeType>
AssocArray<FunctionType,ValueType> reindex( const AssocArray<AnyType, ValueType>& original, FunctionType (SomeType::*getterFunction)() ) {

However, this seems like it would potentially allow functions that are not actually members of ValueType to be called, and so I would prefer some other option. I am not even sure what is wrong, as it appears the templates match, at least with the addition of "ValueType::". Why does the call not match the template, and is there a way to fix it without a fourth templated type?
For more context, Header Containing Implementation and Calling Function.

A:

You have two problems. The first is that reindex implies that the value types are values, but you use them as pointers:
AssocArray<float, test*> floatIndexed;
floatIndexed = reindex( intIndexed, &test::getB );

The second is that reindex's second parameter needs to be declared as a member function, not a free function. So reindex should look like this:
template<class AnyType, class ValueType, class FunctionType>
AssocArray<FunctionType,ValueType *> reindex( const AssocArray<AnyType, ValueType *>& original, FunctionType (ValueType:: *getterFunction)() ) {
    AssocArray<FunctionType, ValueType*> ret;
    FunctionType index;
    for(typename AssocArray<AnyType,ValueType*>::const_iterator it = original.begin(); it!=original.end(); it++) {
        index = ((*it->second)->*getterFunction)();
        ret[index] = it->second;
    }
    return ret;
}

