在 C++ 中使用成员函数向量时,有没有办法实现协变返回类型?

Posted

技术标签:

【中文标题】在 C++ 中使用成员函数向量时,有没有办法实现协变返回类型?【英文标题】:Is there a way to implement covariant return types when using a vector of member functions in C++? 【发布时间】:2019-01-29 15:05:45 【问题描述】:

我的基类看起来像(当然有构造函数):

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[]"

【问题讨论】:

不要使用指向成员函数的指针,gBase 中指向成员函数的指针向量与指向g 成员函数的指针向量不同 .请了解std::function 以获得解决问题的简单方法。 一方面,不同元素类型的向量是不相关的,无论元素类型之间的关系如何。其次,g 私有继承。 【参考方案1】:

即使 TU 是协变的,std::vector&lt;T&gt;std::vector&lt;U&gt; 也不是协变的。对于模板类型,每个特化都是它自己的唯一类型,除了模板名称之外,与其他类型没有任何关系。

您需要的是一个通用类型的向量,您可以使用std::function 获得它。如果两个函数都返回std::vector&lt;std::function&lt;double(double)&gt;&gt;,则派生函数将覆盖基函数。然后,您可以使用捕获 this 的 lambda 填充向量中的函数,因此它具有调用成员函数的对象。

如果你不能这样做,另一种选择是使用std::vector&lt;std::function&lt;double(gbase const*, double)&gt;&gt;,然后你需要传递一个指向要调用函数的对象的指针和参数。

【讨论】:

【参考方案2】:

您必须返回一个std::vector&lt;cdouble (gBase::*)(double)&gt;,因为std::vector&lt;cdouble (gBase::*)(double)&gt;std::vector&lt;cdouble (g::*)(double)&gt; 之间没有关系

另请注意,g[i][alpha](k) 无法调用其中一个函数,因为您不会传递将是 thisg(作为 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;
    
;

【讨论】:

以上是关于在 C++ 中使用成员函数向量时,有没有办法实现协变返回类型?的主要内容,如果未能解决你的问题,请参考以下文章

用向量 c++ 中的指针成员初始化对象

调用 C++ 向量的每个元素的成员函数

使用非静态成员函数的 C++ 排序向量

C++如何调用使用向量的成员函数

C++ - 没有匹配的成员函数调用“push_back”

c ++在析构函数中删除向量类成员内存