是否可以在运行时选择C ++泛型类型参数?

时间:2009-11-14 22:21:03

标签: c++ dynamic templates types generics

有没有办法在运行时选择类的泛型类型,或者这是C ++中的编译时事物?

我想做的就是这样(伪代码):

Generictype type;
if(somveval==1)
    type = Integer;
if(someval==2)
    type = String;

list<type> myList;

这在C ++中是否可行?如果是,怎么样?

5 个答案:

答案 0 :(得分:11)

这是一个编译时间的事情。编译时必须知道模板参数类型。

那就是说,使用某些模板元编程技术,你可以选择一种类型或另一种AT编译时,但只有在编译时知道所有可能的类型,并且只有在选择类型的条件时可以在编译时解决。

例如,使用部分特化,您可以在编译时根据整数选择一个类型:

template <typename T>
class Foo
{ };

template <int N>
struct select_type;

template<>
struct select_type<1>
{
    typedef int type;
};

template<>
struct select_type<2>
{
    typedef float type;
};

int main()
{
    Foo<select_type<1>::type> f1; // will give you Foo<int>
    Foo<select_type<2>::type> f2; // will give you Foo<float>
}

答案 1 :(得分:2)

可以使用Boost.Variant(固定数量的不同类型)或Boost.Any(一种可以存储任何类型的类型,基本上是“无效指针”但具有类型信息)。

如果String和Integer碰巧是从多态基类派生的,那么也是可能的。 (但为此,他们必须实现相同的界面,在您的情况下可能会或可能不会。)

通常,多态性是最简单的方法,而且确实一直使用它。

Variant和Any需要花费大量工作:你仍然需要以某种方式获取他们正在存储的正确类型的内容。 (好像你要使用向下转换为派生类,而不是依赖于多态方法调用。)

答案 2 :(得分:1)

正如其他人也回答的那样,你的问题的答案是“否”,C ++不支持在运行时动态输入。我只是想指出,根据你想要完成的任务,你可以使用 union 模拟这种动态类型,这就是{{ 3}}在COM中实现。

答案 3 :(得分:0)

我想不出这会有用的情况,但是......

#include "boost/variant.hpp"
#include <list>
#include <string>

boost::variant<std::list<int>, std::list<std::string> >
unknown(int someval) {
    if (someval == 1)
        return boost::variant<std::list<int>, std::list<std::string> >(
                std::list<int>());
    else if (someval == 2)
        return boost::variant<std::list<int>, std::list<std::string> >(
                std::list<std::string>());
}

答案 4 :(得分:0)

你最接近的是:

template <typename T>
void do_stuff_with_list
{
    list<T> myList;
    ...
}

enum Type
{
   Integer = 1,
   String
};

void do_stuff(Type type)
{
    switch (type)
    {
    case Integer:
        do_stuff_with_list<int>();
        break;
    case String:
        do_stuff_with_list<string>();
        break;
    };
}