C++ 映射元素上循环的范围
考虑下面的例子C++ 映射元素上循环的范围,c++,c++11,C++,C++11,考虑下面的例子config\u parser是一个类的对象,其方法variable\u map()按值返回类型为std::map的对象。第一个循环给出错误或垃圾结果,而第二个循环给出正确的结果。我错过了什么 使用GCC 6.3.1、clang 3.9.1(c++14)测试的编译器 std::vector rules=config_parser.variable_map()[“CellQRule”]; for(常量自动规则:config_parser.variable_map()[“CellQRu
config\u parser
是一个类的对象,其方法variable\u map()
按值返回类型为std::map
的对象。第一个循环给出错误或垃圾结果,而第二个循环给出正确的结果。我错过了什么
使用GCC 6.3.1、clang 3.9.1(c++14)测试的编译器
std::vector rules=config_parser.variable_map()[“CellQRule”];
for(常量自动规则:config_parser.variable_map()[“CellQRule”]){
std::cout假设config\u parser.variable\u map()
按值返回,那么对于config\u parser.variable\u map()[“CellQRule”];
,config\u parser.variable\u map()
将返回一个临时的std::map
,然后config\u parser.variable\u map()[“CellQRule”]
将返回属于临时std::map
的对std::vector
的引用
这与
{
auto && __range = range_expression ;
auto __begin = begin_expr ;
auto __end = end_expr ;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
注意:在完整表达式之后,临时变量将被销毁;因此在自动&&&uuuuu range=range\u expression;
之后,\uuuuu range
将成为悬挂引用;然后,UB
另一方面,当您使用命名变量而不是临时变量时,一切正常。假设config\u parser.variable\u map()
按值返回,然后对于config\u parser.variable\u map()[“CellQRule”];
,config\u parser.variable\u map()
将返回一个临时的std::map
,然后config_parser.variable_map()[“CellQRule”];
将返回属于临时std::map
的对std::vector
的引用
这与
{
auto && __range = range_expression ;
auto __begin = begin_expr ;
auto __end = end_expr ;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
注意:在完整表达式之后,临时变量将被销毁;因此在自动&&&uuuuu range=range\u expression;
之后,\uuuuu range
将成为悬挂引用;然后,UB
另一方面,当您使用命名变量而不是临时变量时,一切正常。A将是一个良好的开端。您发布的代码没有问题。错误在别处。您确定问题不在variable\u map()中吗
?如果不修改对象,请尝试使用const auto&
而不是const auto
。Doesconfig\u parser.variable\u map()
返回副本或引用?我不知道编译器实际上是如何从基于范围的循环构建迭代的,但是如果它接受您的表达式两次并附加.begin()
和.end()
那么变量映射()
将被调用两次。如果返回一个副本,则开始
和结束
返回的迭代器不属于同一个向量
。如果您打算返回表示该字符串向量的配置解析器
的实际成员,那么您应该返回一个引用,而不是副本。如果没有,我们不知道这是否是您的意图。A将是一个良好的开端。您发布的代码没有任何错误。错误在别处。您确定问题不在variable_map()中吗
?如果不修改对象,请尝试使用const auto&
而不是const auto
。Doesconfig\u parser.variable\u map()
返回副本或引用?我不知道编译器实际上是如何从基于范围的循环构建迭代的,但是如果它接受您的表达式两次并附加.begin()
和.end()
那么变量映射()
将被调用两次。如果返回一个副本,则开始
和结束
返回的迭代器不属于同一个向量
。如果您打算返回表示该字符串向量的配置解析器
的实际成员,那么您应该返回一个引用,而不是副本。如果没有,我们不知道这是否是你的意图。
{
auto && __range = range_expression ;
auto __begin = begin_expr ;
auto __end = end_expr ;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}