2009-11-14 75 views
6

有没有办法在运行时选择类的通用类型,或者这是C++编译时的事情?是否可以在运行时选择C++泛型类型参数?

我想要做的是这样的(伪):

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

list<type> myList; 

在C++中这可能吗?如果是,如何?

+2

一切皆有可能。但是你想要做的事情在C++中并不容易。如果你解释你为什么要这样做,我们可能会给你更好的建议。 – 2009-11-14 23:51:10

回答

10

这是一个编译时的事情。编译时编译器必须知道模板参数类型。这就是说,使用某些模板元编程技术,您可以选择一种或另一种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> 
} 
0

我想不出的情况下,这将是有益的,但&hellip;

#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>()); 
} 
1

正如其他人也回应,您的问题的答案是“否”,C++不支持动态类型在运行时。我只想指出,取决于你想要完成什么,你可能能够模拟这个动态类型使用联合,这是如何在COM中实现VARIANT type

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; 
    }; 
} 
2

这是可能的Boost.Variant(固定数量的不同类型的)或Boost.Any(可以存储任何类型的类型,基本上你的“无效指针“,但带有类型信息)。

这也是可能的,如果字符串和整数碰巧从一个多态基类派生的。 (但为此,他们必须实现相同的界面,在您的情况下可能或不可能)。

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

变异和任何需要使用相当多的工作的:你仍然需要以某种方式获得的内容,因为它们是存储正确的类型。 (排序的,如果你是用的,而不是依靠多态的方法调用向下强制转换到派生类。)