c++ - 从 const 字符串参数获取非常量迭代器
问题描述
我正在使用以下语法读取字符串:
string example {"firstList:[element1:value1,element2:value2];secondList:[elementA:valueA,elementB:valueB]"};
因为一个真正的列表可以有数百个元素,而我只需要读取操作(检查是否value1 == "something"
存在elementA
),我实现了一个std::string::iterator
基于函数来查找给定字符串中的列表。这是一个简化版本:
bool findList(
const std::string &input,
const std::string &listName,
std::string::iterator globalStart,
std::string::iterator globalEnd,
std::string::iterator &listStart,
std::string::iterator &listEnd
)
{
if (input.empty() || listName.empty()) return false;
size_t inicio = input.find(listName);
if (inicio == string::npos) return false;
size_t fin = input.find("]", inicio);
if (fin == string::npos) return false;
listStart = globalStart + inicio + listName.length() + 2;
listEnd = globalStart + fin;
if (listEnd >= globalEnd) return false;
string::iterator badList = std::find(listStart, listEnd, ';');
if (badList != listEnd) return false;
return true;
}
该函数有效,但我必须传递字符串input
, input.begin()
, 并input.end()
为列表迭代器分配值。是否有另一种选择来分配input.begin()
to listStart
(和相同的listEnd
)?
写作:
listStart = input.begin() + inicio + listName.length() + 2;
listEnd = input.begin() + fin;
尝试将 const 迭代器分配给非常量迭代器时会产生编译器错误:
error: no match for ‘operator=’ (operand types are ‘std::__cxx11::basic_string<char>::iterator {aka __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >}’ and ‘__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >’)
listStart = input.begin() + inicio + listName.length() + 2;
我知道通过input
唯一的 asstd::string &input
可以解决问题,但我想保留所需的检查const
。
这是一个最小的例子:
#include <iostream>
#include <string>
#include <algorithm>
#include <assert.h>
using std::cout;
using std::endl;
using std::string;
using std::size_t;
bool findList(
const std::string &input,
const std::string &listName,
std::string::iterator globalStart,
std::string::iterator globalEnd,
std::string::iterator &listStart,
std::string::iterator &listEnd
)
{
if (input.empty() || listName.empty()) return false;
size_t inicio = input.find(listName);
if (inicio == string::npos) return false;
size_t fin = input.find("]", inicio);
if (fin == string::npos) return false;
listStart = globalStart + inicio + listName.length() + 2;
listEnd = globalStart + fin;
if (listEnd >= globalEnd) return false;
string::iterator badList = std::find(listStart, listEnd, ';');
if (badList != listEnd) return false;
return true;
}
int main() {
string example {"firstList:[element1:value1,element2:value2];secondList:[elementA:valueA,elementB:valueB]"};
string::iterator listStart, listEnd;
bool answer = false;
// Test the findList function
answer = findList(example, "firstList", example.begin(), example.end(), listStart, listEnd);
assert(answer == true);
assert(string(listStart, listEnd) == "element1:value1,element2:value2");
cout << "Test firstList passed" << endl;
answer = findList(example, "secondList", example.begin(), example.end(), listStart, listEnd);
assert(answer == true);
assert(string(listStart, listEnd) == "elementA:valueA,elementB:valueB");
cout << "Test secondList passed" << endl;
answer = findList(example, "thirdList", example.begin(), example.end(), listStart, listEnd);
assert(answer == false);
assert(string(listStart, listEnd) == "elementA:valueA,elementB:valueB"); // iterators remain unchanged
cout << "Test thirdList passed" << endl;
return 0;
}
*这是我的第一个问题,请随时指出我可以对帖子做出的任何改进。
解决方案
const std::string::iterator
意思是“字符串的迭代器,通过它可以更改字符串;迭代器不能指向其他任何地方。”
std::string::const_iterator
意思是“字符串的迭代器,不能通过它改变字符串;迭代器可以指向其他地方。”
看起来你混淆了这两个。 input.begin()
返回 a const_iterator
when input
is const
,并且您不能将 a 分配给 a const_iterator
--iterator
这会破坏 const 正确性。
此函数中的所有迭代器都应该是const_iterator
. 将您的函数签名更改为:
bool findList(
const std::string &input,
const std::string &listName,
std::string::const_iterator globalStart,
std::string::const_iterator globalEnd,
std::string::const_iterator &listStart,
std::string::const_iterator &listEnd
) {
// ...
}
然后调用者应该使用str.cbegin()
and str.cend()
。同样,listStart
and listEnd
inmain()
应更改为const_iterator
。
推荐阅读
- jquery - 如何在 svg 类中获取属性
- android - 如何在片段类而不是活动类中使用底页?
- swift - 如何使用 WKWebView / WKHTTPCookieStore 在应用重新启动时保留 cookie
- odoo-12 - 在odoo12中将金额转换为NPR格式的单词?
- javascript - 如何使用 php 在 wordpress 中使用他们的 ID 获取所有用户状态(登录或注销)的列表
- hive - 当使用 oozie 子工作流调用 hive -e 时抛出 NoSuchMethodError
, 从主工作流调用时运行完美 - asp.net-mvc - 找不到控制器名称 .net core 2.0
- python - 更改文件夹中 csv 文件的名称
- javascript - 如何在谷歌地图中找到多边形内的所有地方
- dart - 如何修复“在 Flutter 中未获取 SignInWithgoogle 属性”