Quote:
I don't understand the thing you are shooting.
Part of a simple Recursive Descent Parser using PEG notation.
Quote:
Why should the constructor be responsible for storing information about the "work" `std::string'? Can I reset them at least?
What for ?
Quote:
Do I have to build a new object to apply the same "manipulations/matching" object (derived class?) to a different string?
Yes, that seems to be the simplest and cheapest(I think, compared to storing trees) way to implement memoization later.
Quote:
Why does it even need to operate on a `std::string'? What if I want to do "manipulations/matching" on a file? Do I have to read the entire file in a `std::string'?
Good point.
I guess making them accept generic iterators(this won't need random access, anyway) would solve that problem.
Quote:
What if I don't need a new `std::string'? Do I call your function and toss the `std::string' I don't need?
Not sure when this situation would come up.
When the input needs to be matched against optional targets or "zero or more (*)" and similar cases, it can(possibly) just return an empty string and still denote success.
Quote:
If the `std::string' generated is the result of manipulating my input, why do I need an iterator to the current position?
If the `std::string' is simply a matched instance of the input, the iterator itself should tell me what I need to know to build a string, so why do I need a particular `std::string' result?
Good point(later one is relevant), I guess premature optimization creeped into my though process.
Quote:
Is this functionality intended to be applied iteratively?
If so, why am I responsible for creating a new object, or resetting the old object, when you've already told me the object itself is aware of its position in the input?
The iterator is already going to be an invalid iterator if the "particular functionality" fails to find success, so why do I need a particular "success"/"fail" result when I can just get an iterator?
Does the facilities allow partial success?
Is the iterator returned a valid iterator to the current position even when the functionality in question fails?
Yes.
To refer back to old objects later.
Thats why I thought I needed some cleanup code, to reset the current iterator to begin. Because the matching can still succeed without the iterator having moved.
Not sure..would give some thought to it.
It returns the iterator it was constructed with.(Anything better ?)
Quote:
If your class only serves to implement a single, purposed operation with all mechanisms performed in a constructor you do not, in fact, have a class at all; you have a simple function pretending to be a class.
If I can change neither the "work" string or the operations performed against it, why am I not just calling a function?
It also stores the result for later use.
Inheritance helps to reduce much of the duplicated code in those functions if I overloaded them.
Quote:
If the facilities can be referenced and used anonymously, how could you possibly do the work in a derived constructor?
I need a factory, I think.
It can then construct the correct object according to the 'rules' specified.
They can be used anonymously because the results are of the same nature.
Quote:
Why do I need to call a method to query the validity of a `std::string::iterator' or `std::string' object, all of which are possibly generated by the same function invocation, just to use the results of "certain string manipulations/matching"?
Are these results somehow unrelated? If they aren't unrelated, why don't you just give me the results when I invoke your facility as, seemingly, that is the purpose entirely of the facility in question? If they are unrelated, why are the classes all part of the same hierarchy?
I don't understand this block!
Quote:
Why are you going on about mutating a shared iterator when you can just mutate a copy?
I am using a copy.
By 'reset', I meant the iterator that was to be returned, so that is not invalid.