c++ initializer_list迭代器返回错误的值
initializer list - C++ initializer_list iterator returning wrong value
我有一个这样定义的类:
initializer_list<string> choices;
initializer_list<string>::iterator current_choice;
bool has_choices = false;
MenuItem(Position position, string prompt) { this->position = position; this->prompt = prompt; }
MenuItem(Position position, string prompt, initializer_list<string> choices) : MenuItem(position, prompt) {
this->choices = choices;
this->current_choice = this->choices.begin();
this->text = *(this->current_choice);
this->has_choices = true;
}
当前菜单项定义为MenuItem* current_menu_item = &menuItems[menuItemIndex];
当我在构造函数中迭代initializer_list时,将输出正确的值。但是在后面的代码中,当我尝试切换值时,像这样:
if (c == KEY_RIGHT) {
if (current_menu_item->has_choices)
{
if (current_menu_item->current_choice != current_menu_item->choices.end()) {
current_menu_item->current_choice++;
current_menu_item->text = *(current_menu_item->current_choice);
}
}
}
它显示了下一个菜单项对象的initializer_list的第一个值,我按右键,然后崩溃。如果下一个对象被选中,我按右键,它就崩溃了。
对象被放入一个像这样的向量
menuItems.push_back(MenuItem(Position(5, 15), "Religion: ", { "*", "*", "*", "Protestant" }));
menuItems.push_back(MenuItem(Position(30, 5), "Do you smoke? ", { "Yes", "No" }));
我试着在整个代码的不同点调试,但我似乎无法确定它在哪里或为什么会出错。
没关系,有两个人指出我应该使用常规容器而不是initializer_list。谢谢大家的回答。我现在觉得自己很笨。我所要做的就是将initializer_list更改为vector,而不更改任何其他代码。
选自《工作草案c++, 2012-11-02》
例如,如果我将初始化列表复制到18.9初始化器列表[support.initlist]
initializer_list类型的对象提供了对const e类型对象数组的访问。[注:一对指针或一个指针加一个长度是initializer_list的明显表示。]Initializer_list用于实现8.5.4中指定的初始化器列表。复制初始化列表并不复制底层元素。
std::vector
中,它就可以完美地工作。您应该将choices
定义为常规容器,而不是std::initializer_list
#include <string>
#include <vector>
#include <iostream>
#include <iterator>
struct A {
A(const std::initializer_list<std::string> &args) : v(args) {}
void dump() {
std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, "n"));
}
std::vector<std::string> v;
};
int main(int argc, char **argv)
{
A a({"Hello, ", "world!"});
a.dump();
return 0;
}
不应该在解引用迭代器之后(而不是之前)进行自增操作吗?
current_menu_item->text = *(current_menu_item->current_choice);
current_menu_item->current_choice++;
否则,有可能对end迭代器解引用。
还有另一个问题,正如mfontanini指出的那样,当您调用MenuItem(Position(5, 15), "Religion: ", { "*", "*", "*", "Protestant" })
等时,初始化列表在表达式末尾到期,这意味着您的内部初始化列表指向无效内存(初始化列表仅复制指针)。解决方案是使用像std::vector
这样的标准容器。
第二个构造函数按值复制选项。因此,current_choice
作为迭代器的有效性取决于参数选择的活动性。像{ "*", "*", "*", "Protestant" }
这样的参数保存在堆栈中,因此如果调用push_back
的方法返回,那么choices
可能会消失,并且current_choice作为迭代器变成一个悬垂的"指针"。
- (C++)分析树以计算返回错误值的简单算术表达式
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 我不断收到 [错误] ID 返回 1 退出状态错误,但看不到问题所在
- C++中函数的向量返回类型引发错误
- 有人知道为什么在开关中使用stoi函数会返回恒定的错误吗
- glad 导致 glfwSwapBuffers 返回错误消息
- 将错误返回给调用方而不是立即在 C++ 中抛出错误是否是一种好的做法
- QNX Momentics: GoogleMock - 返回有价值,在函数中返回 void 错误
- 我的模板类方法返回错误类型?
- C++ 中的编译错误:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- 替换WCHAR_T错误返回存储地址
- 错误:void 值未被忽略,因为它应该被忽略,错误:返回语句具有值
- 带有值的递归阶乘错误返回语句,在函数中返回 'void' [-fallowive]
- 存储在静态常量整数 (C++) 中的对数函数的错误返回值
- 更丰富的错误返回消息用于提升::精神::qi 解析
- C++初级逻辑错误-返回0
- 由于进程很多,pthread_create的错误返回代码是 35 错误,我用过pthread_exit应该杀死线程不是吗?
- c++错误处理返回值错误返回
- systememerror:没有异常集的错误返回