[英]Is there a way to implement covariant return types when using a vector of member functions in C++?
我的基类看起来像(当然有构造函数):
class gBase
{
public:
// The user will implement a vector of a vector of functions that can be called as g[i][alpha](k)
virtual vector<cdouble (gBase::*)(double)> operator[] (uint i) = 0;
};
我希望一个可能的实现看起来像这样:
class g : gBase
{
public:
g() : g_funcs({{g_00, g_01}}) {}
vector<cdouble (g::*)(double)> operator[] (uint i)
{
return g_funcs[i];
}
private:
vector<vector<cdouble (g::*)(double)> > g_funcs;
// define each function.
cdouble g_00(double k)
{
return 5.0;
}
cdouble g_01(double k)
{
return 3.0;
}
};
在定义g_funcs时我哪里出错了? 我遇到了这个:
return type is not identical to nor covariant with return type "std::__1::vector<cdouble (gBase::*)(double), std::__1::allocator<cdouble (gBase::*)(double)>>" of overridden virtual function "gBase::operator[]"
即使T
和U
是协变的, std::vector<T>
和std::vector<U>
也不协变。 对于模板类型,每个专门化都是它自己的唯一类型,除了模板名称之外,其他类型都没有关系。
您需要的是通用类型的向量,您可以使用std::function
获得它。 如果两个函数都返回一个std::vector<std::function<double(double)>>
则派生函数将覆盖基函数。 然后,您可以使用捕获了this
的lambda来填充矢量中的函数,以便它具有对象来调用成员函数。
如果您不能执行此操作,则另一种选择是使用std::vector<std::function<double(gbase const*, double)>>
,然后需要将指针传递给您要调用的对象功能加上参数。
您将必须返回std::vector<cdouble (gBase::*)(double)>
,因为std::vector<cdouble (gBase::*)(double)>
与std::vector<cdouble (g::*)(double)>
之间没有关系std::vector<cdouble (g::*)(double)>
还要注意, g[i][alpha](k)
不会调用这些函数之一,因为您没有传递将是this
的g
(作为gBase
)。 你可以代替
(g.*g[i][alpha])(k)
或使用C ++ 17
std::invoke(g[i][alpha], g, k);
但它确实听起来像你要束起来this
与载体的功能。 在这种情况下,您应该
class gBase
{
public:
// The user will implement a vector of a vector of functions that can be called as g[i][alpha](k)
virtual std::vector<std::function<double(double)> > operator[] (uint i) = 0;
};
class g : public gBase
{
public:
g() : g_funcs({{[this](double k){ return g_00(k); }, [this](double k){ return g_01(k); }}}) {}
std::vector<std::function<double(double)> > operator[] (uint i)
{
return g_funcs[i];
}
private:
std::vector<std::vector<std::function<double(double)> > > g_funcs;
// define each function.
cdouble g_00(double k)
{
return 5.0;
}
cdouble g_01(double k)
{
return 3.0;
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.