使用旧式循环,我可以深入研究 aQJsonArray并在下面的示例中为每个数组项添加元素“foo”和现有元素“bar”的内容。我如何使用基于 C++11 的范围来做到这一点?
// QJsonArray oldArray contains an array of which one element is "bar"
QJsonArray newArray;
int i, b = oldArray.count();
for (i=0; i<n; ++i) {
QJsonObject element = oldArray.at(i).toObject();
element["foo"] = element["bar"];
newArray.append(element);
}
Run Code Online (Sandbox Code Playgroud)
我尝试了以下方法(无可否认是反复试验):
for (auto& element : oldArray) {
element["foo"] = element["bar];
newArray.append(element);
}
Run Code Online (Sandbox Code Playgroud)
我收到错误
对类型“QJsonValueRef”的非常量左值引用无法绑定到“QJsonValueRef”类型的临时变量
for (const auto& element : oldArray) {
...
Run Code Online (Sandbox Code Playgroud)
我收到警告
循环变量“元素”始终是副本,因为“QJsonArray”类型的范围不返回引用
for (const auto element : oldArray) {
element["foo"] = element["bar];
...
Run Code Online (Sandbox Code Playgroud)
我收到错误
'const QJsonValueRef' 类型没有可行的重载运算符 []
关系到 element["bar"]
问题是迭代器 forQJsonArray返回一个临时QJsonValueRef对象,而左值引用不能绑定到临时对象。我们可以按值持有该临时文件:
// QJsonArray oldArray contains an array of which one element is "bar"
QJsonArray newArray;
for (auto v : oldArray) {
QJsonObject element = v.toObject();
element["foo"] = element["bar"];
newArray.append(element);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下v是一个QJsonValueRef对象(类似于oldArray.at(i)旧式循环中给出的内容)。之后,我们将其转换QJsonValueRef为QJsonObjectusing .toObject()。
或者我们可以使用转发引用,因为它们可以绑定到右值:
for (auto&& v : oldArray) {
...
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,v被推导为对 a 的右值引用QJsonValueRef。
两种解决方案在创建/销毁的对象数量方面是相同的(因为在前者中,在使用任何体面的编译器时,副本在C++17 保证复制省略规则下甚至在 C++17 之前的版本中被省略。在后者,引用绑定到临时对象,这会延长其生命周期以匹配整个迭代)。
std::vector<bool>时发生的情况。因为两者std::vector<bool>并QJsonArray有返回的代理对象的迭代器。| 归档时间: |
|
| 查看次数: |
3003 次 |
| 最近记录: |