std::iostream/std::cout - Do not compile with vc-8_0

Discussion in 'C++' started by jean.daniel.michaud@gmail.com, Mar 28, 2007.

  1. Guest

    Hi all,

    Something I don't get.
    The code is:

    // snippet on
    #include <list>
    #include <iostream>

    int main()
    {
    std::list<std::eek:stream> list;
    list.push_back(std::cout);
    return 0
    }
    // snippet off

    Compiles with msvc (visual 6) but not with vc-8_0 (visual 2005).

    vc-8_0 output (C:\>cl /EHsc test.cpp) :

    // output on
    test.cpp
    G:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE\ostream(581) :
    error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot
    access private member declared in class
    'std::basic_ios<_Elem,_Traits>'
    with
    [
    _Elem=char,
    _Traits=std::char_traits<char>
    ]
    G:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE
    \ios(151) : see declaration of
    'std::basic_ios<_Elem,_Traits>::basic_ios'
    with
    [
    _Elem=char,
    _Traits=std::char_traits<char>
    ]
    This diagnostic occurred in the compiler generated function
    'std::basic_ostream<_Elem,_Traits>::basic_ostream(const
    std::basic_ostream<_Elem,_Traits> &)'
    with
    [
    _Elem=char,
    _Traits=std::char_traits<char>
    ]
    // output off

    Why ? std::cout is supposed to be a std::eek:stream right ? I tried a
    static_cast<std::eek:stream &>, but no luck...

    Any idea?

    JD
     
    , Mar 28, 2007
    #1
    1. Advertising

  2. Mike Wahler Guest

    <> wrote in message
    news:...
    > Hi all,
    >
    > Something I don't get.
    > The code is:
    >
    > // snippet on
    > #include <list>
    > #include <iostream>
    >
    > int main()
    > {
    > std::list<std::eek:stream> list;
    > list.push_back(std::cout);
    > return 0
    > }
    > // snippet off
    >
    > Compiles with msvc (visual 6) but not with vc-8_0 (visual 2005).
    >
    > vc-8_0 output (C:\>cl /EHsc test.cpp) :
    >
    > // output on
    > test.cpp
    > G:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE\ostream(581) :
    > error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot
    > access private member declared in class
    > 'std::basic_ios<_Elem,_Traits>'
    > with
    > [
    > _Elem=char,
    > _Traits=std::char_traits<char>
    > ]
    > G:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE
    > \ios(151) : see declaration of
    > 'std::basic_ios<_Elem,_Traits>::basic_ios'
    > with
    > [
    > _Elem=char,
    > _Traits=std::char_traits<char>
    > ]
    > This diagnostic occurred in the compiler generated function
    > 'std::basic_ostream<_Elem,_Traits>::basic_ostream(const
    > std::basic_ostream<_Elem,_Traits> &)'
    > with
    > [
    > _Elem=char,
    > _Traits=std::char_traits<char>
    > ]
    > // output off


    Standard library containers (such as std::list) impose requirements
    upon the types of object they can contain. These requirements are
    that these objects must be copyable and assignable. Stream types
    do not meet this requirement. If you must group streams into a
    'collection', you'll need to store pointers to them instead of
    the stream objects themselves. BTW what specifically is your
    intended purpose of using a container of stream objects?

    >
    > Why ? std::cout is supposed to be a std::eek:stream right ? I tried a
    > static_cast<std::eek:stream &>, but no luck...


    Don't guess. Using a cast to 'fix' a compiler warning or error is
    almost always the wrong thing to do.

    -Mike
     
    Mike Wahler, Mar 28, 2007
    #2
    1. Advertising

  3. Guest

    >
    > Standard library containers (such as std::list) impose requirements
    > upon the types of object they can contain. These requirements are
    > that these objects must be copyable and assignable. Stream types
    > do not meet this requirement. If you must group streams into a
    > 'collection', you'll need to store pointers to them instead of


    Ok, but why msvc would compile it then ? And why this compiles with
    vc-8_0:
    // snippet on
    #include <list>
    #include <iostream>

    int main()
    {
    std::list<std::eek:stream> list;
    return 0;
    }
    // snippet off

    I have created a list of ostream... It should not compile has ostream
    does not satisfies the requirements you enounce.

    > the stream objects themselves. BTW what specifically is your
    > intended purpose of using a container of stream objects?
    >
    >


    I'm trying to write a log library. This list of streams is just the
    list of output for my logger object. Make use of pointers here will
    just make the usage of the library harder. User will have to use new,
    and therefore delete...

    >
    > > Why ? std::cout is supposed to be a std::eek:stream right ? I tried a
    > > static_cast<std::eek:stream &>, but no luck...

    >
    > Don't guess. Using a cast to 'fix' a compiler warning or error is
    > almost always the wrong thing to do.
    >


    I know, I saw this on a previous post on the same pb, so I wanted to
    step aside this potential answer.

    JD
     
    , Mar 28, 2007
    #3
  4. wrote:
    >> Standard library containers (such as std::list) impose requirements
    >> upon the types of object they can contain. These requirements are
    >> that these objects must be copyable and assignable. Stream types
    >> do not meet this requirement. If you must group streams into a
    >> 'collection', you'll need to store pointers to them instead of

    >
    > Ok, but why msvc would compile it then ? And why this compiles with
    > vc-8_0:
    > // snippet on
    > #include <list>
    > #include <iostream>
    >
    > int main()
    > {
    > std::list<std::eek:stream> list;
    > return 0;
    > }
    > // snippet off
    >
    > I have created a list of ostream... It should not compile has ostream
    > does not satisfies the requirements you enounce.


    You've not done anything that would actually invoke the code requiring
    the functionality 'ostream' lacks. Try pushing anything in.

    > [..]


    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Mar 28, 2007
    #4
  5. Fei Liu Guest

    wrote:
    >> Standard library containers (such as std::list) impose requirements
    >> upon the types of object they can contain. These requirements are
    >> that these objects must be copyable and assignable. Stream types
    >> do not meet this requirement. If you must group streams into a
    >> 'collection', you'll need to store pointers to them instead of

    >
    > Ok, but why msvc would compile it then ? And why this compiles with
    > vc-8_0:
    > // snippet on
    > #include <list>
    > #include <iostream>
    >
    > int main()
    > {
    > std::list<std::eek:stream> list;
    > return 0;
    > }
    > // snippet off
    >


    msvc doesn't actually instantiate any template source code that would
    facilitate the missing copy semantic in std::eek:stream. It only
    instantiates upon demand.
     
    Fei Liu, Mar 28, 2007
    #5
  6. Old Wolf Guest

    On Mar 29, 6:51 am, wrote:
    > > Standard library containers (such as std::list) impose requirements
    > > upon the types of object they can contain. These requirements are
    > > that these objects must be copyable and assignable. Stream types
    > > do not meet this requirement. If you must group streams into a
    > > 'collection', you'll need to store pointers to them instead of

    >
    > Ok, but why msvc would compile it then ? And why this compiles with
    > vc-8_0:


    Most compilers still compile some programs even though they don't
    comply with the C++ standard.
     
    Old Wolf, Mar 29, 2007
    #6
  7. Guest

    >
    > Standard library containers (such as std::list) impose requirements
    > upon the types of object they can contain. These requirements are
    > that these objects must be copyable and assignable. Stream types
    > do not meet this requirement. If you must group streams into a
    > 'collection', you'll need to store pointers to them instead of
    > the stream objects themselves. BTW what specifically is your
    > intended purpose of using a container of stream objects?
    >


    Ok, so to avoid using pointers, I'm trying the shared_ptr, but I still
    have difficulties with ostream.
    In this code, I add to a list a reference to an ostream. When I try to
    access it, I have a crash.

    // Snippet on
    #include <list>
    #include <string>
    #include <iostream>
    #include <boost/shared_ptr.hpp>

    int main()
    {
    std::list<boost::shared_ptr<std::eek:stream> > l;

    boost::shared_ptr<std::eek:stream> p(&std::cout);
    *p << "on the shared pointer" << std::endl;
    l.push_back(p);

    std::list<boost::shared_ptr<std::eek:stream> >::iterator it =
    l.begin();
    std::cout << "before loop" << std::endl;
    while (it++ != l.end())
    {
    boost::shared_ptr<std::eek:stream> p2 = *it;
    *p2 << "test" << std::endl;
    }

    return 0;
    }
    // snippet off

    I have somthing like:
    // output on
    on the shared pointer
    before loop
    segmentation fault
    // output off

    dereferencing p2 should give me my ostream. It works on p... Any idea?

    JD
     
    , Mar 29, 2007
    #7
  8. Matteo Guest

    On Mar 29, 10:44 am, wrote:

    > Ok, so to avoid using pointers, I'm trying the shared_ptr, but I still
    > have difficulties with ostream.
    > In this code, I add to a list a reference to an ostream. When I try to
    > access it, I have a crash.
    >
    > // Snippet on
    > #include <list>
    > #include <string>
    > #include <iostream>
    > #include <boost/shared_ptr.hpp>
    >
    > int main()
    > {
    > std::list<boost::shared_ptr<std::eek:stream> > l;
    >
    > boost::shared_ptr<std::eek:stream> p(&std::cout);
    > *p << "on the shared pointer" << std::endl;
    > l.push_back(p);
    >
    > std::list<boost::shared_ptr<std::eek:stream> >::iterator it =
    > l.begin();
    > std::cout << "before loop" << std::endl;
    > while (it++ != l.end())
    > {
    > boost::shared_ptr<std::eek:stream> p2 = *it;
    > *p2 << "test" << std::endl;
    > }
    >
    > return 0;}
    >
    > // snippet off
    >
    > I have somthing like:
    > // output on
    > on the shared pointer
    > before loop
    > segmentation fault
    > // output off
    >
    > dereferencing p2 should give me my ostream. It works on p... Any idea?
    >
    > JD


    First off, a boost::shared_pointer will delete its pointee by default.
    You can overcome that by passing in a null deleter to the shared
    pointer constructor (details in the boost::shared_ptr docs). With what
    you have, the shared pointer will call delete on &cout when the last
    shared pointer is destructed (at the end of the program). This will
    almost certainly cause a crash of some sort.

    I'm not sure why you're getting a segfault before "test" is output,
    since std::endl is supposed to flush buffers (I believe). If I'm
    wrong, your program could be crashing at program termination due to
    what I said above, but before all the buffers are flushed (certainly,
    if you had used <<"\n" instead of <<std::endl, thats what I would have
    guessed).

    I'm not sure that what you are doing is necessarily the best way to
    achieve what you want, but as I have no ther suggestions, try using a
    null deleter, and report back.

    -matt
     
    Matteo, Mar 29, 2007
    #8
  9. Guest

    > First off, a boost::shared_pointer will delete its pointee by default.
    > You can overcome that by passing in a null deleter to the shared
    > pointer constructor (details in the boost::shared_ptr docs). With what
    > you have, the shared pointer will call delete on &cout when the last
    > shared pointer is destructed (at the end of the program). This will
    > almost certainly cause a crash of some sort.
    >


    Yes obviously, I forget that but that is obvious.
    Here is the code, that produce the same result.

    // snippet on
    #include <list>
    #include <string>
    #include <iostream>
    #include <boost/shared_ptr.hpp>

    struct null_deleter { void operator()(void const *) const {} };

    int main()
    {
    std::list<boost::shared_ptr<std::eek:stream> > l;

    boost::shared_ptr<std::eek:stream> p(&std::cout, null_deleter());
    *p << "on the shared pointer" << std::endl;
    l.push_back(p);

    std::list<boost::shared_ptr<std::eek:stream> >::iterator it =
    l.begin();
    std::cout << "before loop" << std::endl;
    while (it++ != l.end())
    {
    boost::shared_ptr<std::eek:stream> p2 = *it;
    *p2 << "test" << std::endl;
    }

    return 0;
    }
    // snippet off

    > I'm not sure why you're getting a segfault before "test" is output,
    > since std::endl is supposed to flush buffers (I believe). If I'm
    > wrong, your program could be crashing at program termination due to
    > what I said above, but before all the buffers are flushed (certainly,
    > if you had used <<"\n" instead of <<std::endl, thats what I would have
    > guessed).


    Actually it really crashes on the streaming. I debugged it with gdb.
    It crashes on:
    std::eek:stream::sentry::sentry () from /usr/lib/libstdc++.so.6

    > I'm not sure that what you are doing is necessarily the best way to
    > achieve what you want, but as I have no ther suggestions, try using a
    > null deleter, and report back.


    What I am trying to do is to have a pool of streams where to write on.
    The user add streams to the list, pass this to my library, and then I
    shall manage deallocation. I don't want the user to mess around with
    shared_ptr and I dont want him to allocate pointer either (RIIA, RAAI
    or RIAA, I don't remember the term :) ...)

    Thanks for your help.

    JD
     
    , Mar 30, 2007
    #9
    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. Pmb

    std::cout vs cout

    Pmb, Jun 2, 2004, in forum: C++
    Replies:
    2
    Views:
    4,449
    Leor Zolman
    Jun 2, 2004
  2. Stefan Ram

    Re: cout vs std::cout

    Stefan Ram, Sep 28, 2008, in forum: C++
    Replies:
    7
    Views:
    513
  3. saurabh29789

    Sending std::cout to std::cout !!

    saurabh29789, Jun 11, 2009, in forum: C++
    Replies:
    1
    Views:
    313
    Harald Finster
    Jun 11, 2009
  4. saurabh29789

    Sending std::cout to std::cout

    saurabh29789, Jun 11, 2009, in forum: C++
    Replies:
    2
    Views:
    359
    Rolf Magnus
    Jun 12, 2009
  5. , India
    Replies:
    3
    Views:
    2,974
    James Kanze
    Nov 13, 2010
Loading...

Share This Page