【发布时间】:2015-02-25 05:02:12
【问题描述】:
有人能告诉我为什么递归operator= 没有在这里编译吗?任务很简单。我有一个Menu<T> 类,其中T 是菜单中每个选项的类型。 Menu<WeightedItem<T>> 类只是 Menu<T> 的特化,其中 WeightedItem<T> 包含项目 T 以及 int 数据成员(用于概率目的)。
我想通过使用其项目并附加一些概率权重(其值与问题无关)将Menu<T> 转换为Menu<WeightedItem<T>>。问题是菜单可以有子菜单,而子菜单又可以有子菜单,因此我需要递归使用operator=。到目前为止,这是我的代码:
template <typename T> struct WeightedItem;
template <typename T>
struct Menu
{
struct Option
{
const T item;
Menu* submenu;
Option* next;
Option(const T& t, Menu<T>* menu = nullptr)
: item(t),
submenu(menu),
next(nullptr)
{}
};
Option* first; // first option in the menu
};
template <typename T>
struct WeightedItem {
T item;
int probabilityWeight;
};
template <typename T>
struct Menu<WeightedItem<T>>
{
struct Option
{
const WeightedItem<T> item;
Menu* submenu;
Option* next;
Option(const WeightedItem<T>& t, Menu<WeightedItem<T>>* menu = nullptr)
: item(t),
submenu(menu),
next(nullptr)
{}
Option& operator=(const Option& other)
{
// Needed for defining Menu& operator=(const Menu<T>&).
if (this == & other)
return *this;
item = other.item;
submenu = other.submenu;
next = other.next;
return *this;
}
};
Option* first;
Menu & operator=(const Menu<T>&);
};
template <typename T>
Menu<WeightedItem<T>>& Menu<WeightedItem<T>>::operator=(const Menu<T>& other)
{
delete first;
if (!other.first)
first = nullptr;
else
{
int weight = 1;
Menu<WeightedItem<T>> submenu operator=(*other.first->submenu); // Recursive operator= call for submenus. Won't compile.
first = new Menu<WeightedItem<T>>::Option({other.first->item, weight}, &submenu);
Option* current = first->next;
for (typename Menu<T>::Option* o = other.first->next; o; o = o->next)
{
Menu<WeightedItem<T>> submenu operator=(*o->submenu); // Recursive operator= call for submenus. Won't compile.
current = new Menu<WeightedItem<T>>::Option({o->item, ++weight}, &submenu);
current = current->next;
}
}
return *this;
}
struct Item {};
int main() {
Menu<Item> menu;
Menu<WeightedItem<Item>> weightedMenu;
weightedMenu = menu;
}
但是这两个递归调用似乎是非法的。为什么?
[Error] expected initializer before 'operator'
如果是非法的,如何解决?
更新:
好的,所有的深度复制都使用new 进行了多次分配。我不得不简单地放弃 operator= 的想法,而是简单地定义一个递归函数。我测试了结果也是准确的:
template <typename T> struct WeightedItem;
template <typename T>
struct Menu {
struct Option {
const T item;
Menu* submenu;
Option* next;
Option (const T& t, Menu<T>* menu = nullptr): item(t), submenu(menu), next(nullptr) {}
};
Option* first = nullptr;
};
template <typename T>
struct WeightedItem {
T item;
int probabilityWeight;
};
template <typename T>
struct Menu<WeightedItem<T>> {
struct Option {
const WeightedItem<T> item;
Menu* submenu;
Option* next;
Option (const WeightedItem<T>& t, Menu<WeightedItem<T>>* menu = nullptr): item(t), submenu(menu), next(nullptr) {}
};
Option* first = nullptr;
inline void inheritFrom (const Menu<T>&);
};
template <typename T>
inline void Menu<WeightedItem<T>>::inheritFrom (const Menu<T>& other) {
if (!other.first)
first = nullptr;
else {
int weight = 1;
Menu<WeightedItem<T>>* submenu = nullptr;
if (other.first->submenu) {
submenu = new Menu<WeightedItem<T>>;
submenu->inheritFrom (*other.first->submenu); // Recursive call for submenus.
}
first = new Menu<WeightedItem<T>>::Option ({other.first->item, weight}, submenu);
Option *current = first->next, *prev = first;
for (typename Menu<T>::Option* o = other.first->next; o; o = o->next) {
Menu<WeightedItem<T>>* submenu = nullptr;
if (o->submenu) {
submenu = new Menu<WeightedItem<T>>;
submenu->inheritFrom (*o->submenu); // Recursive call for submenus.
}
current = new Menu<WeightedItem<T>>::Option ({o->item, ++weight}, submenu);
prev->next = current;
if (o->next) {
prev = current;
current = current->next;
}
}
}
}
struct Item {};
int main() {
Menu<Item> menu;
Menu<WeightedItem<Item>> weightedMenu;
weightedMenu.inheritFrom(menu);
}
但是,关于递归使用 = 的原始问题仍未得到解答。而且看来c++不支持,因为当我尝试用=翻译上面的时候,它没有编译。
【问题讨论】:
-
请贴出编译器给出的错误信息。
-
Menu<WeightedItem<T>> submenu = *o->submenu;不调用任何operator =;这是初始化而不是赋值。 -
使用
Menu<WeightedItem<T>> submenu operator= (*other.first->submenu);?仍然无法编译。 -
您不应在作业中使用“操作员”一词。
标签: c++ variable-assignment operator-keyword