使用函数指针作为参数匹配模板失败

Failure to Match Template Using Function Pointer as Argument

本文关键字:失败 参数 函数 指针      更新时间:2023-10-16

我正试图编写一个函数,该函数将对任何键的std::映射和给定的类指针进行操作,并根据类中函数的返回值创建一个新的std::映射和一个索引。本质上,是一个模板函数,用于根据映射所包含类中的函数重新索引映射。但是,我在尝试调用函数时遇到了编译器错误。

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::"。为什么调用与模板不匹配,有没有办法在没有第四个模板化类型的情况下修复它?

有关更多上下文,请参阅包含实现和调用函数的标头。

您有两个问题。首先,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;
}

您似乎试图将rindex()函数与成员一起使用,但您的函数被声明为使用非成员。这行不通。这不起作用的原因是您需要一个对象来访问类的函数或数据成员。

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*。