是否可以在函数中将类型作为参数?

时间:2010-08-19 15:47:10

标签: c++

我正在尝试为数据库类编写一个函数,它基本上只是一个包含由ID号索引的对象(比如形状)的hash_map的包装器,它将查找ID并将其转换为适当的指针类型。 / p>

e.g。我希望能够做到这样的事情:

Circle* shapeToLookup = NULL;
int idNum = 12;
database.lookup(idNum, circleToLookup);
if(circleToLookup != NULL)
{
    // Do stuff with the circle.
}

让数据库知道其参数的类型。有没有办法在没有重载函数的情况下执行此操作(lookup(int, Circle*)lookup(int, Rect*),ad nauseum)?你可以声明一个像lookup(int, Shape*)这样的函数,让它知道它给出了哪种类型?

谢谢!

3 个答案:

答案 0 :(得分:4)

template <T>
Database::lookup(int idNum, T TobjectToLookup)
{
    // inside here, T is the type of the object passed in/
}

答案 1 :(得分:3)

您可以使用模板进行此操作。

编辑:基于额外信息的新实施。如果mymapstd::map<int, Shape*>

template <typename T>
void lookup(int idNum, T* &ptr) {
    auto it = mymap.find(idNum);
    if (it == mymap.end()) {
        ptr = 0;
    } else {
        ptr = dynamic_cast<T*>(*it); // Shape must have a virtual member function
    }
}

或者您可能更喜欢:

template <typename T>
T* lookup(int idNum) {
    auto it = mymap.find(idNum);
    if (it == mymap.end()) {
        return 0;
    }
    return dynamic_cast<T*>(*it);
}

然后将其称为Circle *circle = database.lookup<Circle>(123);

显然,多态容器本身就是一堆乐趣,但我会假设你已经排序了。在那里我可能遗漏了shared_ptr

当我认为数据库可能存储POD副本时的旧实现:

template <typename T>
void lookup(int idNum, T* &ptr) {
    void *theresult = // something based on idNum

    // some check needed here that theresult really is the right type.
    // how you do this depends on the database, but suppose that
    // the database gives us some integer "type" which indicates the type
    if (type != type_constant<T>::value) {
        ptr = 0;
    } else {
        ptr = static_cast<T*>(theresult);
    }
}

type_constant是“类型特征”的一个例子,你可以像:

那样实现它
template <typename T>
struct type_constant {};

template <>
struct type_constant<Circle> {
    static const int value = 1;
};

template <>
struct type_constant<Rectangle> {
    static const int value = 2;
};

// etc...

答案 2 :(得分:0)

其他人已经解释了如何将类型传递给函数(通过使用函数模板)。我想提出另一种观点:

Shape上引入新的虚拟函数,然后将Do stuff with the Circle部分移动到Cricle类中的虚拟函数的重新实现可能更好。

这样,您就无需了解类型。您只需从数据库中获取Shape对象,然后调用doStuff()函数 - 它会根据Shape的实际类型执行正确的操作。虚函数的一个很好的用例。 : - )

当然,这可能或多或少变得简单,具体取决于Do stuff实际做了什么。