从常量字符串参数中获取一个非常量迭代器



我正在读取具有以下语法的字符串:

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;
}

该函数有效,但我必须传递字符串inputinput.begin()input.end()来为列表迭代器分配值。是否有其他选项将input.begin()分配给listStart(listEnd也是如此(?

写作:

listStart = input.begin() + inicio + listName.length() + 2;
listEnd = input.begin() + fin;

尝试将常量迭代器分配给非常量迭代程序时产生编译器错误:

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作为std::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的意思是";字符串的迭代器,通过它可以更改字符串;迭代器不能指向其他地方">

CCD_ 14表示";字符串的迭代器,通过该迭代器不能更改字符串;迭代器可以指向其他地方">

看起来你把这两个搞混了。当inputconst时,input.begin()返回const_iterator,并且不能将const_iterator分配给iterator——这将破坏常量正确性。

这个函数中的所有迭代器都应该是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()str.cend()。同样地,main()中的listStartlistEnd应该被改变为const_iterator

最新更新