2012-02-10 4 views
1

Я пытаюсь написать функцию, которая будет работать на std :: map любого указателя ключа и класса, предоставленного ему, и создать новую std :: map с индексированием на возвращаемое значение функции в классе. По сути, функция шаблона для переопределения карты на основе функции в ее содержащемся классе. Однако при попытке вызвать эту функцию возникают ошибки компилятора.Невозможность сопоставления шаблона с использованием указателя функции в качестве аргумента

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; 
} 

Вызывается:

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

Где getB имеет тип с плавающей точкой.

Это приводит к ошибке компилятора:

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 (*)()) 

Я пробовал разные варианты этого, в том числе с использованием "FunctionType (ValueType :: * getterFunction)()" и изменения "AssocArray" на "AssocArray". Только один, который работал добавил четвертый аргумент шаблона:

template<class AnyType, class ValueType, class FunctionType, class SomeType> 
AssocArray<FunctionType,ValueType> reindex(const AssocArray<AnyType, ValueType>& original, FunctionType (SomeType::*getterFunction)()) { 

Однако, это кажется, что это потенциально может позволить функции, которые на самом деле не члены ValueType, чтобы назвать, и поэтому я предпочел бы какой-то другой вариант. Я даже не уверен, что не так, как кажется, соответствует шаблону, по крайней мере, с добавлением «ValueType ::». Почему вызов не соответствует шаблону, и есть ли способ исправить его без четвертого шаблонного типа?

Дополнительный контекст: Header Containing Implementation и Calling Function.

+0

Можете ли вы сказать мне ошибку, которую вы получаете при попытке FunctionType (ValueType :: * getterFunction)() без 4-го параметра шаблона? – Sharad

+0

Ваш код ожидает указатель функции, и вы передаете ему указатель на функцию-член. С какими особенностями этого вы смущены? – ildjarn

+0

Ошибка FunctionType (ValueType :: * getterFunction)(), потому что я забыл включить изменение возвращаемого значения «AssocArray » в «AssocArray »; 'template AssocArray reindex (const AssocArray & original, FunctionType (ValueType :: * getterFunction)())' – Bakaiya

ответ

0

У вас есть две проблемы. Первое, что reindex означает, что типы значений значения, но использовать их в качестве указателей:

AssocArray<float, test*> floatIndexed; 
floatIndexed = reindex(intIndexed, &test::getB); 

второй является то, что второй параметр reindex «s должен быть объявлен как функции-члена, а не свободной функции. Так reindex должен выглядеть следующим образом:

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; 
} 
+0

Этот шаблон/определение функции. Я считаю, что ошибка заключалась в том, что когда я попробовал ValueType *, я забыл изменить его и для возвращаемого значения. – Bakaiya

0

Похоже, что вы пытаетесь использовать функцию rindex() с элементами, но ваша функция объявлена ​​для использования нечленами. Это не сработает. Причина, по которой это не будет работать, - это то, что вам нужен объект для доступа к функциям или членам данных класса.

0
template<class A, class B> 
class X{ 
public: 

}; 

class Y{ 
public: 
    int func() { return 42; } 
}; 

template<class A, class B, class C> 
X<C,B> reindex(const X<A, B>& original, C (B::*getterFunction)()) { 
    X<C, B> x2; 
     cout << "hello" << endl; 
    return x2; 
} 

int main() { X x1; reindex(x1,&Y::func); return 0;

}

Это работает и дает вполне достоверные результаты.

Проблема с вашим вызовом AssocArray intIndexed - это тот факт, что вы пытаетесь передать & test :: getB в качестве функции getter, которая предполагает valueType = test, где в качестве вашего фактического типа значения используется test *.

Смежные вопросы