2013-12-09 25 views
0

我写了Qt的一个小编辑器。它接受一个指针,并根据属性的类型(由字符串决定),它将使用模板化函数从数据中提取数据。我可以注册调用基于定义其类型的字符串特定的模板功能的功能?

(例如,如果类型为“点”,它会调用上的指针getBoundValue<QPoint3>。)

这工作得很好实践。但是我将它设置为一个库,以便其他人可以使用它,我假设他们会添加对其他类型的支持。问题是,我不想让他们不得不修改原来的源代码,但是从类继承任何注册或新类型的回调。我不知道如何实现后一种选择,因为我无法将字符串类型和类类型一起传递,可以吗?

如果我想允许用户添加为自己的类型的支持,他们将不得不执行处理这些值我的属性编辑器的一个子类?或者是有办法,我可以重新安排我的代码,以便用户可以在功能可能传递到处理新的类型,如“矩形”,和类型矩形这是电话getBoundValue<Rectangle>()

下面是一些示例代码,其中我看到,如果对象是一个特定类型。如果是这样,我把它匹配的模板函数:

AttributeEditor::update(Bindable* instance) { 
    _instance = instance; 
    clear(); 

    for (int i = 0; i < _instance->attributeCount(); i++) { 
     Attribute attr = _instance->at(i); 

     QList<QStandardItem*> attributeRow; 
     QStandardItem* nameItem = new QStandardItem(
      attribute->property("name").toString() 
     ); 

     attributeRow << nameItem; 

     QList< QList<QStandardItem*> > subRows; 

     if (attr->property("getter").isValid()) { 

      std::cout << attr->type().toStdString() << std::endl; 

      QString value = "?"; 
      if (attr->type() == "point3" || attr->type() == "vector3") { 
       QVector3D p = getBoundValue<QVector3D>(_instance, attr); 

       /* ... */ 
      } 

    /* ... */ 
} 
+0

东西要记住的是,模板是一个*编译时的现象*。如果你发现自己试图在运行时使用模板来做事情......我会建议你可能使用了错误的工具。无论如何......为了完整性,你能否提供你的'Attribute'的定义,并且可能为你真正要实现的目标提供更多的上下文? – HostileFork

回答

1

因为你的代码不会知道外部类,模板或否则,你将需要公开接受以下注册机制:

  1. 类型名称(字符串)。例如“矩形”
  2. 接口

接口应具有称为getBoundValue纯虚拟方法。所有需要该功能的类都应该实现该接口。

例子:

struct IShape { 
    virtual QVector3D getBoundValue() = 0; 
    // more shape methods 
    ... 
}; 

class Rectangle { 
    QVector3D getBoundValue(); 
}; 

// register interface prototype - exported from your library 
void RegisterShape(IShape* pShape, const QString& name); 
+0

我最终做了这样的事情,但使用了一个“处理程序”类,因为每个属性类型都需要实现一组函数,用户不必分别注册每一个。 – voodoogiant

+0

就是这样做的,接口保存所有的方法,所以你只需注册接口。 – egur