Re: How does this work...

From: Mark P (not_at_my.real.email)
Date: 03/01/05


Date: Tue, 01 Mar 2005 01:44:18 GMT

Michael wrote:
>
>
> On Tue, 1 Mar 2005, Mark P wrote:
>
>> Michael wrote:
>>
>>> The following code snippet is from Accelerated C++, but I don't
>>> understand how it can work:
>>>
>>> typedef vector<string> Rule;
>>> typedef vector<Rule> Rule_collection;
>>> typedef map<string, Rule_collection> Grammar;
>>>
>>> // read a grammar from a given input stream
>>> Grammar read_grammar(istream& in)
>>> {
>>> Grammar ret;
>>> string line;
>>>
>>> // read the input
>>> while (getline(in, line)) {
>>>
>>> // `split' the input into words
>>> vector<string> entry = split(line);
>>>
>>> if (!entry.empty())
>>> // use the category to store the associated rule
>>> ret[entry[0]].push_back(
>>> Rule(entry.begin() + 1, entry.end()));
>>> }
>>> return ret;
>>> }
>>>
>>>
>>> The bit I don't understand is this line:
>>>
>>> ret[entry[0]].push_back(Rule(entry.begin() + 1, entry.end()));
>>>
>>> More specifically, the bil I don't understand is the 'Rule' bit
>>> because its not an object. Can someone please explain how that code
>>> is valid.
>>>
>>> Cheers
>>> Micheal
>>
>>
>> It's invoking the constructor for Rule, one form of which takes two
>> iterators as arguments, and creating an unnamed object which is then
>> inserted into ret[entry[0]]. This form of the constructor copies the
>> elements between the two iterators to initialize the newly created
>> object.
>>
>
> I understand that ret[entry[0]] refers to a vector<Rule>, so wouldn't
> ret[entry[0]].push_back be using the .push_back method of the vector
> class? and in this case require a vector<Rule> type for the .push_back
> method? (sorry if Im using the right terminology).

ret[entry[0]] is a vector<Rule>, in other words a version of vector
which contains Rule objects. The push_back method is that of the vector
class, specifically of the vector<Rule> class, and therefore the
argument should be a Rule object. Such a rule object is created by
Rule(entry.begin() + 1, entry.end()) [see below].
>
> I can understand that using 'Rule' can create and unnamed vector<string>
> object, but why does the (entry.begin() + 1, entry.end()) following it
> fill the unnamed object without an operand?
>

This is one of several defined constructors for a vector object. Look
at http://www.sgi.com/tech/stl/Vector.html if you have no other STL
reference and note in particular the member

template <class InputIterator>
vector(InputIterator, InputIterator)

That is the form of the constructor being invoked.

> This is very confusing C++ for me ;)
>
> Cheers
> Michael



Relevant Pages

  • Re: How does this work...
    ... Michael wrote: ... the bil I don't understand is the 'Rule' bit because ... It's invoking the constructor for Rule, one form of which takes two ... elements between the two iterators to initialize the newly created object. ...
    (alt.comp.lang.learn.c-cpp)
  • Re: list<class A*> l;
    ... > Because every insertion can throw. ... > And what about insertion with iterators? ... In the copy constructor I have try/catch blocks, ... so it is not safe to call the destructor). ...
    (comp.lang.cpp)
  • Re: Passing Data Between Forms
    ... I was trying to decide if passing the form to the constructor like you ... did would be better than using public static variables, ... >> Michael C. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Convert from std::vector<double> to std::vector<int>
    ... > constructor that takes a pair of iterators. ... template ... value_type operator (const From& f) const ... iterator categories (like forward iterators must return references). ...
    (comp.lang.cpp)
  • Re: a question about classes
    ... Note - this declares a constructor. ... - create unnamed object of type X ... - destroy return-value object ...
    (alt.comp.lang.learn.c-cpp)