根据参数类型,只调用容器的匹配对象

时间:2013-06-06 18:18:47

标签: c++ generics

全部 我有一个容器的容器,例如,

class ShapeBase {};
class Rect: public Shape {
void set(class Diag diag);
};
class Circle: public Shape {
void set(class Radi radi);
};

现在我有一个应用程序类来调用这个形状列表。我的意图是 只会根据参数类型调用列表元素。

像这样的东西。

 class application {
    typedef std::list<ShapeBase*> List;
    List shapeList; 

    void set(class ???) {
    for (List::iterator it = shapeList.begin(); it != shapeList.end(); ++it)
    {
        // with in the loop of all objects in list,
        // only object with matching argument will be called  
        set(class ???);
    };

因此应用程序类根本不知道具体的形状。

如何在C ++中实现?

1 个答案:

答案 0 :(得分:0)

不幸的是,当您设置定义时,您尝试使用对象列表进行操作相当困难。建立的一个问题是在编译时没有RectDiag的关联,所以你必须告诉编译器Rectangles期望特定的构造函数参数。一种解决方案是模板application::set方法,然后为每个Shape专门化该模板。

下面是一些伪代码(不保证编译):

template<typename ShapeType>
void fillShapeTypeList(std::list<ShapeType*> fillList) {
    for (List::iterator it = this.shapeList.begin(); 
              it != this.shapeList.end(); ++it) {
        if (ShapeType *shape = dynamic_cast<ShapeType>(*it)) {
            fillList.push_back(shape);
        }
    }
}

template<typename ShapeType, typename ShapeSetter>
void set(ShapeSetter setter) {
    std::list<ShapeType*> fillList;
    fillShapeTypeList(fillList);
    for (std::list<ShapeType*>::iterator it = this.shapeList.begin(); 
             it != this.shapeList.end(); ++it) {
        (*it)->set(setter);
    }
}

void set(Diag setter) {
    set<Rect, Diag>(setter);
}

void set(Radi setter) {
    set<Circle, Radi>(setter);
}

在没有使用“替换失败不是错误”模式的Rect / Circle特定设置器的情况下,还有另一种更复杂的方法可以让它工作 - 但这不值得努力对于这种情况。

一般来说,你应该问问自己,如果你没有明白如何让编译器做你想做的事情,你做的是否正确。在这种情况下,您可能最好注册带有应用程序的对象的回调,或者使指定类型的所有形状都查看中心对象以确定信息大小。