operator >> needs to be in namespace std??

Discussion in 'C++' started by Noah Roberts, Dec 18, 2006.

  1. Noah Roberts

    Noah Roberts Guest

    template < typename T >
    std::istream & operator >> (std::istream & in, std::pair<T,T> & p)
    {
    in >> p.first >> p.second;
    return in;
    }


    ....
    std::istream_iterator< std::pair<size_type, size_type> >
    in_beg(std::cin), in_end;
    ....


    fails to compile. Wrapping the operator >> for the pair in namespace
    std {} works. Since you're not "allowed" to insert stuff into
    namespace std why is that seemingly required and how could this be done
    without that?
    Noah Roberts, Dec 18, 2006
    #1
    1. Advertising

  2. Noah Roberts wrote:

    > template < typename T >
    > std::istream & operator >> (std::istream & in, std::pair<T,T> & p)
    > {
    > in >> p.first >> p.second;
    > return in;
    > }
    >
    >
    > ...
    > std::istream_iterator< std::pair<size_type, size_type> >
    > in_beg(std::cin), in_end;
    > ...
    >
    >
    > fails to compile. Wrapping the operator >> for the pair in namespace
    > std {} works. Since you're not "allowed" to insert stuff into
    > namespace std why is that seemingly required and how could this be done
    > without that?


    Looks like an ADL thing. Care to post a complete example so I can try to
    compile it here? I want to be sure I'm doing things exactly as you are.
    I'm not sure what the ramifications of std::eek:perator>>(...) might be.

    --
    NOUN:1. Money or property bequeathed to another by will. 2. Something handed
    down from an ancestor or a predecessor or from the past: a legacy of
    religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
    from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
    Steven T. Hatton, Dec 18, 2006
    #2
    1. Advertising

  3. Noah Roberts wrote:
    > template < typename T >
    > std::istream & operator >> (std::istream & in, std::pair<T,T> & p)
    > {
    > in >> p.first >> p.second;
    > return in;
    > }
    >
    >
    > ...
    > std::istream_iterator< std::pair<size_type, size_type> >
    > in_beg(std::cin), in_end;
    > ...
    >
    >
    > fails to compile. Wrapping the operator >> for the pair in namespace
    > std {} works. Since you're not "allowed" to insert stuff into
    > namespace std why is that seemingly required and how could this be done
    > without that?
    >


    I thought you were allowed to add things to the std namespace (namely
    overloads of pre-existing operators - just like this). There was a
    discussion about this a couple of years ago, and I do remember two sides
    of the argument, however I can't remember how definitive the discussion was.
    Gianni Mariani, Dec 18, 2006
    #3
  4. Gianni Mariani wrote:

    > Noah Roberts wrote:
    >> template < typename T >
    >> std::istream & operator >> (std::istream & in, std::pair<T,T> & p)
    >> {
    >> in >> p.first >> p.second;
    >> return in;
    >> }
    >>
    >>
    >> ...
    >> std::istream_iterator< std::pair<size_type, size_type> >
    >> in_beg(std::cin), in_end;
    >> ...
    >>
    >>
    >> fails to compile. Wrapping the operator >> for the pair in namespace
    >> std {} works. Since you're not "allowed" to insert stuff into
    >> namespace std why is that seemingly required and how could this be done
    >> without that?
    >>

    >
    > I thought you were allowed to add things to the std namespace (namely
    > overloads of pre-existing operators - just like this).


    Curiously, this works:

    #include <iostream>

    template < typename T >
    std::eek:stream& operator<<(std::eek:stream& out, std::pair<T,T>& p) {
    return out << p.first << p.second;
    }


    int main() {
    std::pair<int,int> p(1,4);
    std::cout<<p<<std::endl;
    }

    In truth, even if adding the symbol to std works and is "acceptable", I
    would like to know why it is necessary.

    > There was a
    > discussion about this a couple of years ago, and I do remember two sides
    > of the argument, however I can't remember how definitive the discussion
    > was.

    I defer to the Standard.
    --
    NOUN:1. Money or property bequeathed to another by will. 2. Something handed
    down from an ancestor or a predecessor or from the past: a legacy of
    religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
    from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
    Steven T. Hatton, Dec 18, 2006
    #4
  5. Noah Roberts

    Noah Roberts Guest

    Gianni Mariani wrote:

    > I thought you were allowed to add things to the std namespace (namely
    > overloads of pre-existing operators - just like this). There was a
    > discussion about this a couple of years ago, and I do remember two sides
    > of the argument, however I can't remember how definitive the discussion was.


    Took a sec to find it but it's there:

    17.4.3.1 is where it states a program can't add declarations or
    definitions to namespace std. However, it states you *can* add
    template specializations. "Such a specialization (complete or partial)
    of a standard library template results in undefined behavior unless the
    declaration depends on a user-defined name of external linkage and
    unless the specialization meets the standard library requirements for
    the original template."

    I'm a little confused here though. Why is it *necissary* that operator
    >> be defined in namespace std? Does that function qualify as a template specialization?
    Noah Roberts, Dec 18, 2006
    #5
  6. Noah Roberts

    White Wolf Guest

    Noah Roberts wrote:
    > Gianni Mariani wrote:
    >
    >> I thought you were allowed to add things to the std namespace (namely
    >> overloads of pre-existing operators - just like this). There was a
    >> discussion about this a couple of years ago, and I do remember two sides
    >> of the argument, however I can't remember how definitive the discussion
    >> was.

    >
    > Took a sec to find it but it's there:
    >
    > 17.4.3.1 is where it states a program can't add declarations or
    > definitions to namespace std. However, it states you *can* add
    > template specializations. "Such a specialization (complete or partial)
    > of a standard library template results in undefined behavior unless the
    > declaration depends on a user-defined name of external linkage and
    > unless the specialization meets the standard library requirements for
    > the original template."
    >
    > I'm a little confused here though. Why is it *necissary* that operator
    >>> be defined in namespace std? Does that function qualify as a template
    >>> specialization?


    It does not count as a template specialization. It is a definition of a
    brand new template. And I am afraid, reading the text of the standard you
    posted, that it is not "legal".

    However there is another "rule" you break: do not use std::pair for your own
    types. Use them as members, or private inheritance, but not directly as a
    user defined type.

    For the practical side: if you are only using this printing function as a
    debugging tool, I would say you are quite safe and it will work as expected.

    ....I am just thinking that does a template instance of std::pair count as
    user defined type... But I don't think it does. It would not make sense.
    But I am not a language lawyer so I might be very wrong.


    --
    WW aka Attila
    :::
    Business - the art of extracting money from another man's pocket without
    resorting to violence. -- Max Amsterdam
    White Wolf, Dec 19, 2006
    #6
  7. Noah Roberts

    Stefan Naewe Guest

    White Wolf schrieb:

    > However there is another "rule" you break: do not use std::pair for your own
    > types. Use them as members, or private inheritance, but not directly as a
    > user defined type.


    Why not ?

    > ...


    Stefan
    --
    Stefan Naewe
    stefan_DOT_naewe_AT_atlas_DOT_de
    Stefan Naewe, Dec 19, 2006
    #7
  8. Noah Roberts

    Noah Roberts Guest

    Stefan Naewe wrote:
    > White Wolf schrieb:
    >
    > > However there is another "rule" you break: do not use std::pair for your own
    > > types. Use them as members, or private inheritance, but not directly as a
    > > user defined type.

    >
    > Why not ?


    bump...

    yeah, why not?
    Noah Roberts, Dec 23, 2006
    #8
  9. Noah Roberts

    Default User Guest

    Noah Roberts wrote:

    >
    > Stefan Naewe wrote:
    > > White Wolf schrieb:
    > >
    > > > However there is another "rule" you break: do not use std::pair
    > > > for your own types. Use them as members, or private inheritance,
    > > > but not directly as a user defined type.

    > >
    > > Why not ?

    >
    > bump...


    "Bump"? What does that mean?



    Brian
    Default User, Dec 23, 2006
    #9
  10. Noah Roberts

    Bo Persson Guest

    Noah Roberts wrote:
    > Stefan Naewe wrote:
    >> White Wolf schrieb:
    >>
    >>> However there is another "rule" you break: do not use std::pair
    >>> for your own types. Use them as members, or private inheritance,
    >>> but not directly as a user defined type.

    >>
    >> Why not ?

    >
    > bump...
    >
    > yeah, why not?


    Because std::pair isn't a user defined type? :)

    One problem in particular is that it doesn't have operator>> and operator<<
    defined, and you are formally not allowed to define those inside namespace
    std. :)))



    Bo Persson
    Bo Persson, Dec 24, 2006
    #10
  11. Noah Roberts

    Noah Roberts Guest

    Bo Persson wrote:
    > Noah Roberts wrote:
    > > Stefan Naewe wrote:
    > >> White Wolf schrieb:
    > >>
    > >>> However there is another "rule" you break: do not use std::pair
    > >>> for your own types. Use them as members, or private inheritance,
    > >>> but not directly as a user defined type.
    > >>
    > >> Why not ?

    > >
    > > bump...
    > >
    > > yeah, why not?

    >
    > Because std::pair isn't a user defined type? :)
    >
    > One problem in particular is that it doesn't have operator>> and operator<<
    > defined, and you are formally not allowed to define those inside namespace
    > std. :)))


    You can't define operator >> for pair outside namespace std because you
    can't use pair for your own types because you formally can't define
    operator >> inside of std??

    Oh well. Either it's a bug in MS C++ and it's perfectly ok to define
    an operator >> for pair outside of namespace std or both G++ and Comeau
    are the ones that are broken. Since nobody seems to have a clear idea
    why it shouldn't be perfectly ok my money is on MS being wrong, again.
    Noah Roberts, Dec 25, 2006
    #11
  12. Noah Roberts

    Bo Persson Guest

    Noah Roberts wrote:
    > Bo Persson wrote:
    >> Noah Roberts wrote:
    >>> Stefan Naewe wrote:
    >>>> White Wolf schrieb:
    >>>>
    >>>>> However there is another "rule" you break: do not use std::pair
    >>>>> for your own types. Use them as members, or private
    >>>>> inheritance, but not directly as a user defined type.
    >>>>
    >>>> Why not ?
    >>>
    >>> bump...
    >>>
    >>> yeah, why not?

    >>
    >> Because std::pair isn't a user defined type? :)
    >>
    >> One problem in particular is that it doesn't have operator>> and
    >> operator<< defined, and you are formally not allowed to define
    >> those inside namespace std. :)))

    >
    > You can't define operator >> for pair outside namespace std because
    > you can't use pair for your own types because you formally can't
    > define operator >> inside of std??
    >
    > Oh well. Either it's a bug in MS C++ and it's perfectly ok to
    > define an operator >> for pair outside of namespace std or both G++
    > and Comeau are the ones that are broken. Since nobody seems to
    > have a clear idea why it shouldn't be perfectly ok my money is on
    > MS being wrong, again.


    It is perfectly legal to define operator>> for std::pair outside of
    namespace std. It just doesn't always work, because name lookup sometimes
    doesn't find it.

    We are not allowed to add overloads inside namespace std, because there is a
    blanket statement banning this (17.4.3.1). It says that we are allowed to
    add specializations that depend on user defined names, but nothing else.
    This allows the implementation to have any number of overloads as an
    implementation detail.

    The catch 22 for std::pair is that we know that standard doesn't specify any
    operator>> overload for it. If it did, we wouldn't have any problems! So, in
    practice it is almost certain that we could add an overload to namespace
    std, *except* for the fact that the standard explicitly says that we cannot
    ("undefined behavior").


    Bo Persson
    Bo Persson, Dec 25, 2006
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Petter Reinholdtsen
    Replies:
    9
    Views:
    4,341
    Howard
    Nov 29, 2004
  2. Geoffrey S. Knauth
    Replies:
    6
    Views:
    980
    Earl Purple
    Jan 18, 2006
  3. Replies:
    7
    Views:
    415
    Jacek Dziedzic
    Oct 3, 2006
  4. Martin T.
    Replies:
    7
    Views:
    807
    Martin T.
    Mar 10, 2008
  5. curiousEngine
    Replies:
    1
    Views:
    1,350
    James Kanze
    May 9, 2008
Loading...

Share This Page