简体   繁体   English

在C ++中使用成员函数向量时,是否有一种方法可以实现协变返回类型?

[英]Is there a way to implement covariant return types when using a vector of member functions in C++?

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? 在定义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. 即使TU是协变的, std::vector<T>std::vector<U>也不协变。 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 . 您需要的是通用类型的向量,您可以使用std::function获得它。 If both functions return a std::vector<std::function<double(double)>> then the derived function will override the base one. 如果两个函数都返回一个std::vector<std::function<double(double)>>则派生函数将覆盖基函数。 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. 然后,您可以使用捕获了this的lambda来填充矢量中的函数,以便它具有对象来调用成员函数。

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. 如果您不能执行此操作,则另一种选择是使用std::vector<std::function<double(gbase const*, double)>> ,然后需要将指针传递给您要调用的对象功能加上参数。

You will have to return a std::vector<cdouble (gBase::*)(double)> , because there is no relation between std::vector<cdouble (gBase::*)(double)> and std::vector<cdouble (g::*)(double)> 您将必须返回std::vector<cdouble (gBase::*)(double)> ,因为std::vector<cdouble (gBase::*)(double)>std::vector<cdouble (g::*)(double)>之间没有关系std::vector<cdouble (g::*)(double)>

Note also that g[i][alpha](k) isn't going to work to call one of those functions, as you aren't passing a g (as a gBase ) that will be this . 还要注意, g[i][alpha](k)不会调用这些函数之一,因为您没有传递将是thisg (作为gBase )。 You could instead 你可以代替

(g.*g[i][alpha])(k)

Or with C++17 或使用C ++ 17

std::invoke(g[i][alpha], g, k);

But it really sounds like you want to bundle up this with the functions in the vector. 但它确实听起来像你要束起来this与载体的功能。 In that case you should have 在这种情况下,您应该

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM