My base class will look something like (with constructors of course):
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;
};
and I want a possible implementation to look something like this:
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;
}
};
Where am I going wrong in defining g_funcs? I run into this:
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[]"
A std::vector<T>
and std::vector<U>
are not covariant even if T
and U
are covariant. With template types, each specialization is it's own unique type with no relation to the other besides the template name.
What you need is a vector of a common type, and you can get that using std::function
. If both functions return a std::vector<std::function<double(double)>>
then the derived function will override the base one. You could then populate the functions in the vector by using a lambda that captures this
so it has the object to call the member function on.
If you can't do that another option would be to use a std::vector<std::function<double(gbase const*, double)>>
and then you would need pass a pointer to the object you want to call the function on plus the parameter.