簡體   English   中英

從 const 字符串參數獲取非常量迭代器

[英]Get a non-const iterator from a const string parameter

我正在使用以下語法讀取字符串:

string example {"firstList:[element1:value1,element2:value2];secondList:[elementA:valueA,elementB:valueB]"};

由於一個真正的列表可以有數百個元素,而我只需要讀取操作(檢查value1 == "something"elementA是否存在),我實現了一個基於std::string::iterator的 function 來查找給定列表中的列表細繩。 這是一個簡化版本:

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

function 有效,但我必須傳遞字符串inputinput.begin()input.end()來為列表迭代器分配值。 是否有另一個選項可以將input.begin()分配給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作為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表示“字符串的迭代器,通過它可以更改字符串;迭代器不能指向其他任何地方。”

std::string::const_iterator的意思是“字符串的迭代器,通過它不能更改字符串;迭代器可以指向其他地方。”

看起來你混淆了這兩個。 input.begin()inputconst時返回一個const_iterator ,並且您不能將const_iterator分配給iterator ——這會破壞 const 正確性。

這個 function 中的所有迭代器都應該是const_iterator 將您的 function 簽名更改為:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM