需要覆盖反方差解决方法 [英] Override contra-variance workaround needed

查看:207
本文介绍了需要覆盖反方差解决方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法找到(我相信是非常常见的)设计模式来解决以下问题。考虑这段代码:

I'm having difficulty finding the (what I'm sure is a very common) design pattern to work around the following problem. Consider this piece of code:

class AA {};
class BB : public AA {};

class A
{
public:
    virtual void foo(AA& aa) = 0;
};

class B : A
{
public:
    void foo(BB& bb){cout<<"B::foo"<<endl;}
};

int main()
{
    B b;
    BB bb;
    b.foo(bb);
}

此代码将无法编译,因为类B不覆盖纯虚函数'foo'。编译器考虑foo,因为B只声明为对foo的重载,因为在overriden函数的输入参数中不允许协方差。

This code will not compile because the class B does not override the pure virtual function 'foo'. The compiler considers the foo that B declares only as an overload to foo because co-variance is not allowed in input parameters in overriden functions.

现在,我明白了这个的原因。事实上,B从A继承,意味着它应该能够处理对参数为AA类型的foo的任何调用,并且前面的代码没有实现来处理除BB外的任何参数类型。

Now, I understand the reason for this. The fact that B inherits from A means that it should be able to handle any calls to foo with parameters of type AA, and the previous code gave no implementation to handle any parameter type except BB.

当然,我可以在B的foo实现中将aa转换为BB,但是我正在寻找一个保留类型安全性的解决方案,并且实际上迫使B类的实现者也实现继承自AA的类以便代码编译。在理想的情况下,我可以编写一个类似这样的伪代码:

Of course I could just cast the aa to BB in B's foo implementation, but I'm looking for a solution that preserves type-safety and actually forces the implementer of B class to also implement a class that inherits from AA in order for the code to compile. In an ideal world I would be able to write something that looks like this pseudo-code:

class A
{
public:
    abstract class AA{}; //indicates that any child of A must implement also child of AA
    abstract void foo(AA& aa);
};

class B : public A
{
public:
    class BB : AA{}; //will not compile without this
    void foo(BB& bb){cout<<"B::foo"<<endl;}
};

有没有办法在C ++中实现类似的东西? (可能通过某种映射对象而不需要继承)

Is there a way to achieve something similar to this in C++? (boost maybe, by some kind of mapping object without the need for inheritance)

请注意,实际上(与示例不同),BB和AA之间的继承是至关重要的因为AA有许多共享许多质量的孩子,最后我想要实现的是遍历A类的向量,并且只使用适当的参数(AA的向量)运行'foo'。

Please note that in actuality (unlike in the example), inheritance between BB and AA is crucial as AA has many children that share many qualities, and in the end what I want to accomplish is to iterate over a vector of A classes and run 'foo' only with appropriate parameters (vector of AA's)

推荐答案

为了提供类型安全,您应该使用模板而不是继承。

To provide type safety, you should use templates instead of inheritance.

class AA {};
class BB : AA {};

template <typename Managed> class FooManager {
    virtual void foo(Managed& m) { /* default implementation */ }
};

class B : public FooManager<BB> {
    void foo(BB bb) { cout << "B:foo()" << endl; }
};

稍后在代码中,例如,如果要遍历数组,

Later in the code, for example, if you want to traverse an array,

template<typename Managed> void processAll(vector<Managed> v, FooManager<Managed> mgr) {
    for(Managed& m : v) mgr.foo(m);
}

B b;
vector<BB> bbs;
processAll(bbs, b);

编辑:typo fix

typo fix

这篇关于需要覆盖反方差解决方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆