模板对象是否可以更改其类型
Can a template object change its type?
我有以下类
template <typename T> class Item {
public:
T item;
Item () : item( T() ) {}
Item (T arg) { this->item = arg;}
operator T () const {
return item;
}
};
现在,我想编写一个赋值运算符,它还可以更改对象的类型。这可能吗?我在谷歌上搜索过,但没有任何相关内容(顺便说一句,这让我觉得我可能有点疯了)。
为了说明这一点,假设我有以下两个对象:
Item <int> intItem = 3;
Item <double> doubleItem = 3.4;
我想能够写
intItem = doubleItem;
然后,我希望intItem的类型为Item<double>
。
如果我只想要一个"经典"的赋值运算符,如果在我的课堂上,我有类似的东西,它会很好地工作
Item<int>& operator= (const Item<double> & var) {
this->item = var.item;
return *this;
}
双倍值会被四舍五入,但它会起作用。哦,intItem的类型将保持为Item<int>
附言:我知道工会和有标签的工会,我不想用这些。我的Item
类的行为应该"有点像"标记的联合。
所以请给我一个答案,或者告诉我我在做梦。
不,您不能在运行时更改类型,因为模板是编译时的事情。
事实上,这就像将一个变量声明为int
并尝试将其更改为float
。是的,您可以将变量分配给另一个float
变量,但不能更改实际变量的类型。
在此之后,我希望intItem的类型为Item。
这是不真实的,因为intItem
在编译时具有Item<int>
类型,而不是在运行时。
正如前两个答案所写,不,您不能在运行时更改模板的类型。
但是你可以用不同的方式来满足你的要求。取以下代码:
class Item
{
Item()
: data(NULL) {}
template <typename T>
Item(T d)
{
data = new Data<T>(d);
}
Item(const Item& other)
: data(NULL)
{
if (other.data != NULL)
{
data = other.data->clone();
}
}
~Item()
{
delete data;
}
const Item& operator = (const Item& other)
{
if (this != &other)
{
delete data;a
data = NULL;
if (other.data != NULL)
{
data = other.data->clone();
}
}
return *this;
}
template <typename T>
operator T () const
{
Data<T>* d = dynamic_cast<Data<T>*>(data);
if (d != NULL)
{
return d->data;
}
else
{
throw std::bad_cast("");
}
}
private:
struct DataBase
{
virtual ~DataBase() {}
virtual DataBase* clone() = 0;
};
template <typanme T>
struct Data
{
Data(T d)
: data(d) {}
virtual DataBase* clone()
{
return new Data<T>(*this);
}
T data;
};
DataBase* data;
};
这基本上实现了一个Any
类。例如,您可能希望查看boost::any
中的现有实现。
如果你只需要支持少量的类型,你就可以实现一些类似变体的东西:
class Item
{
enum Type
{
NONE,
INT,
DOUBLE
};
Item()
: type(NONE) {}
Item(int value)
: type(INT)
{
intValue = value;
}
Item(double value)
: type(DOUBLE)
{
doubleValue = value;
}
Item(const Item& other)
{
type = other.type;
switch (type)
{
case INT:
intValue = other.intValue;
break;
case DOUBLE:
doubleValue = other.doubleValue;
break;
}
}
~Item()
{
// delete any pointer types
}
const Item& operator = (const Item& other)
{
if (this != &other)
{
type = other.type;
switch (type)
{
case INT:
intValue = other.intValue;
break;
case DOUBLE:
doubleValue = other.doubleValue;
break;
}
}
return *this;
}
operator int () const
{
switch (type)
{
case NONE:
return 0;
case INT:
return intValue;
break;
case DOUBLE:
return static_cast<int>(doubleValue);
break;
}
}
operator double () const
{
switch (type)
{
case NONE:
return 0;
case INT:
return static_cast<double>(intValue);
break;
case DOUBLE:
return doubleValue;
break;
}
}
private:
Type
union {
int intValue;
double doubleValue;
};
};
相关文章:
- std::unordered_map 类型对象声明期间出现"field has incomplete type"错误
- C++ 多态模板类,模板类型对象的实例化
- 如何分配适合容纳 T 类型对象的缓冲区(可能过度对齐、可能有运算符 new 等)
- 如何构造一个 std::variant 类型对象,其自身 Templated 和构造函数转发参数
- C++:初始化指向具有不同类型对象的指针数组
- 在类 C++ 中构造的模板类型对象
- 如何将颁发者名称设置为x509_req类型对象
- 将任何数据类型/对象作为参数传递以确定其大小
- 将引用类型对象的数组从C#封送到C++
- <T> 从类型对象创建类型<T1>对象的构造函数
- C++是否有现有的方法来检查对象是否是派生类型对象
- C 模板:创建与现有对象相同的类型对象
- 链接列表中的虚函数 - 多种返回类型(对象)
- 没有适当操作员()的类型对象的呼叫
- 制作垫子类型对象的数组.输出窗口显示同一帧
- 抽象类型对象的分配
- 在std::list中就地创建自定义类型对象
- 接受泛型列表类型对象的参数
- C++-将模板类型对象强制转换为特定的数据类型
- 试图在C++中打印存储在类型对象数组中的信息