Нет неявного upcasting с аргументами указателей на функции?

Это странная ситуация, с которой я столкнулся. Я ожидал, что указатель будет неявно отклонен:

struct BaseClass
{};

struct DerivedClass : BaseClass
{};

void baseClassArgFunc(BaseClass* arg) {}            // Function taking BaseClass argument
void derivedClassArgFunc(DerivedClass* arg) {}      // Function taking DerivedClass argument

int main()
{
void (*pBaseFuncArg) (BaseClass*);      // Pointer to function taking BaseClass argument
void (*pDerivedFuncArg) (DerivedClass*);    // Pointer to function taking DerivedClass argument

pBaseFuncArg = baseClassArgFunc;            // Assign pointer, works fine
pDerivedFuncArg = derivedClassArgFunc;      // Assign pointer, works fine

pBaseFuncArg = derivedClassArgFunc;         // A value of type void (*) (DerivedClass *arg) cannot be
// assigned to an entity of type void (*) (BaseClass *)

pDerivedFuncArg = baseClassArgFunc;         // A value of type void (*) (BaseClass *arg) cannot be
// assigned to an entity of type void (*) (DerivedClass *)

return 0;
}

Я ожидал, что назначение void (*) (DerivedClass *) для void baseClassArgFunc (BaseClass * arg) будет безопасным. Я не совсем понимаю. Я предполагаю, что нет неявного upcasting с аргументами указателя функции тогда?

2

Решение

Изменение ваших классов, чтобы выявить проблемы:

struct BaseClass
{
};

struct DerivedClass : BaseClass
{
int a;
};

затем

pBaseFuncArg = derivedClassArgFunc;

небезопасно для:

 void derivedClassArgFunc(DerivedClass* arg) { arg->a = 42; }int main()
{
void (*pBaseFuncArg) (BaseClass*) = derivedClassArgFunc;
BaseClass base;

//derivedClassArgFunc(&base); // Doesn't compile as expected
pBaseFuncArg(&base);          // Would be UB, base->i won't exist
}
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]