有没有办法在运行时选择类的泛型类型,或者这是C ++中的编译时事物?
我想做的就是这样(伪代码):
Generictype type;
if(somveval==1)
type = Integer;
if(someval==2)
type = String;
list<type> myList;
这在C ++中是否可行?如果是,怎么样?
答案 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;
};
}