Неверное сопоставление шаблона с использованием указателя на функцию в качестве аргумента - PullRequest
1 голос
/ 11 февраля 2012

Я пытаюсь написать функцию, которая будет работать с 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 ::».Почему вызов не соответствует шаблону, и есть ли способ исправить его без четвертого шаблонного типа?

Для получения дополнительной информации, Реализация, содержащая заголовок и Вызов функции .

Ответы [ 3 ]

0 голосов
/ 11 февраля 2012

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

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

Во-вторых, второй параметр reindex должен быть объявлен как функция-членне бесплатная функция.Так что 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 голосов
/ 11 февраля 2012
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;</p> <p>}

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

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

0 голосов
/ 11 февраля 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...