我有以下课程
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>
。
如果我只想要一个&#34;经典&#34;赋值运算符,如果在我的课程中,我会有类似
的东西,它会工作得很好Item<int>& operator= (const Item<double> & var) {
this->item = var.item;
return *this;
}
double值将被舍入,但它会起作用。哦,intItem的类型将保持Item<int>
P.S。:我知道工会和被标记的工会,我不想用它。我的Item
课程应该表现得像&#34;类似于&#34;标记的工会。
所以请给我一个答案,或者告诉我,我在做梦。
答案 0 :(得分:6)
不能在运行时更改类型,因为模板是编译时的事情。
实际上,将变量声明为int
并尝试将其更改为float
。是的,您可以将变量分配给另一个float
变量,但不能更改实际变量的类型。
答案 1 :(得分:2)
在此之后,我希望intItem的类型为Item。
这是不真实的,因为intItem
在编译时具有类型Item<int>
,而不是在运行时。
答案 2 :(得分:1)
正如之前的两个答案所写的那样,不能在运行时更改模板的类型。
但是你可以用不同的方式满足你的要求。请使用以下代码:
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;
};
};