【发布时间】:2018-09-19 03:41:02
【问题描述】:
考虑一下
class Base { };
class Derived : public Base { };
Base *f1(Derived *) { return {}; }
Derived *f2(Derived *) { return {}; } // covariant
Base *f3(Base *) { return {}; } // contravariant
Derived *f4(Base *) { return {}; } // covariant & contravariant
using Callback = Base *(*)(Derived *);
Callback pfunc1 = f1; // works of course
// These won't work...
Callback pfunc2 = f2;
Callback pfunc3 = f3;
Callback pfunc4 = f4;
// So I have to make a wrapper for each
Base *f2_wrap(Derived *d)
{
return f2(d);
}
Base *f3_wrap(Derived *d)
{
return f3(d);
}
Base *f4_wrap(Derived *d)
{
return f4(d);
}
// Now it works
Callback pfunc2 = f2_wrap;
Callback pfunc3 = f3_wrap;
Callback pfunc4 = f4_wrap;
那么为什么我不能将函数指针设置为以Derived 对象作为返回值的函数,或以Base 对象作为参数的函数(在c# 委托中有效)?
我知道我可以使用包装函数,但为什么它不是语言功能的一部分?
【问题讨论】:
-
协变指针和引用结果类型支持覆盖虚函数。但仅此而已。原始函数指针本质上是 C 的东西。但是,我相信您至少可以将
std::function用于协变。不确定std::function强制执行的规则的确切内容,但我认为这是非常宽松的,例如,如果您提供的函数指针或仿函数对象可以使用模板参数指定的参数和结果存储来调用 ,那么就OK了。
标签: c++ oop function-pointers covariance contravariance