12:28
2
A: C++ arithmetic calculator built without resorting to tree structure as conventionally done, but by parsing input string and then std::stoi

CalethUse the tools the library provides You can greatly simplify your string manipulations by using std::string::replace, e.g. std::string inside_parentheses{input.substr(idx_open_bracket+1, idx_close_bracket-idx_open_bracket-1)}; // perform operations inside parentheses ( ) parseMultDivMod(inside_pa...

I think string::replace() invalidates the iterators though? Other points taken. I think if I wrap each number in brackets as I suggest in a comment to the answer by @G.Sliepen, perhaps I can eliminate all edge cases and really really streamline the code to reflect the logic behind it in hi-fi. Also, isn't const std::string& == std::string_view?
@Giogre assigning over it also invalidates iterators, of which you have none. No, string view is a good replacement for const ref, particularly for taking substrings, as it doesn't copy
At the end of the loop, I use string.assign(new_string) which overwrites string with new content and deletes the old. Iterators are ready and working for the next iteration in the loop. If I were to use replace() to insert the parentheses result in the middle of the input string, I would break iterators for the next iteration
@Giogre You are not using any iterators. You take the index of a character after replacing content of input with assign. You can do the same, take the index of a character after replacing content of input with replace.
You might be right. I thought the various string methods I use inside my loops require a range internally, but perhaps not one with valid iterators ?
12:28
@Giogre What I'm suggesting is replacing everything from std::string plug_result{}; to input.assign(plug_result) with input.replace(...). I.e. the part where you replace part of input with something else
@Giogre I think you misunderstand what "invalidates iterators" means. When you have a std::string::iterator that points somewhere, and do something to the std::string that causes it to reallocate, that iterator no longer points anywhere. You can still assign a new iterator value to that, and it will then point to the new location. In the same way, your indexes no longer point to ( and ) when you replace the bracket with a number, but you don't use those indexes after that, you reassign them
Ok let's say the program replaces a single operation in parentheses inside the string with its result, so we remove 5 chars from the middle of the string and replace them with 1 char. What I knew is that iterators from the point of insertion forward, up to the end of the string are invalidated. You write about assigning new iterators: I take you intend the programmer has to manually do it, create an iterator object in a statement. Then, you can easily get to the end of the string as its contents are stored contiguously, but I am not sure about a complete (begin, end) string traversal
Hello I just logged in
Iterators are a generalisation of pointers. std::string::iterator is allowed to be an alias for char *
would probabl;y make sense to have a complete *begin, end( traversal in a contiguous data structure if the inserted iterator is restored
*(begin, end) traversal, sorry
* stands not for dereferencing, just a typing error!
What invalidation means, is that if you have a char * pointing at some part of the string, operations on the string that reallocate can, as action-at-a-distance, make that pointer no longer point to a char
Any of the non-const members of std::string can do that, which makes all pointers, references and iterators to elements of the string invalid
And all of this doesn't matter, because you don't have any char *s, char &s or std::string::iterator objects in your loops
if memory content is moved, a pointer pointing to the old memory address would be undefined behaviour I guess
12:35
the pointer still exists, but it can't be dereferenced
contents can be anything left in that memory address
ok exactly
But importantly you don't have any of those
And also assign also can invalidate pointers, references and iterators
sure but I totally reassign the whole string
so its a brand new block of memory. You mean even with assign() I would have to redefine the iterator
in any case I worked with indices
Yes. Which also stop pointing where they used to. Consider what happens when you evaluate 2*(3+4). You replace (3+4) with 7, so the index for ) is now off the end of the string.
Which doesn't matter, because you aren't using it anymore.
ok. It's just a reflex that I have to instinctly steer away from replace or insert() in vector like structures
12:42
Which is why I'm saying there's no difference between creating the string 2*7 and assigning that to input, and calling input.replace(2, 5, "7")
if I follow with find(input.begin(), input.end(), '7') will it work? I guess yes. Only a previously defined iterator auto my_iter{input[3]} will be left invalidated
would auto my_iter{input[0]} be invalidated?
Yes, calling begin and end after changing the string still works
auto my_iter{input[0]} declares a char, not a char&
So there's nothing to invalidate
auto my_iter{input.begin()} then
declared before the input.replace taking place
Yes, that would be invalidated
But it would also be invalidated by input.assign
Anyways your countenance suggests me you-re British
middle class native stock
my angle is that I'm looking for a job and I'm in England too
EU settled but I cannot gauge how based you are from your "politics" profile
you will have to excuse my uncouth bluntness
I see these chats have public access