Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why this code can't compile?

3 views
Skip to first unread message

David Lee

unread,
Feb 9, 2006, 9:35:14 PM2/9/06
to
Hi, all
I got the following code from
http://builder.com.com/5100-6370_14-5079969.html,
but it can't compile, neither can I figure out how to fix it. Anyone
pls give me an
explanation?

1 #include <string>
2 #include <sstream>
3 #include <iostream>
4
5 class str_stream
6 {
7 public:
8 std::stringstream & underlying_stream() const
9 { return m_streamOut; }
10
11 operator std::string() const
12 {
13 return m_streamOut.str();
14 }
15
16 private:
17 mutable std::stringstream m_streamOut;
18 };
19
20 template<class T>
21 const str_stream & operator<< (const str_stream & out, const T
& value)
22 {
23 out.underlying_stream() << value;
24 return out;
25 }
26
27 int main()
28 {
29 int num = 48;
30 std::string str;
31
32 // str_stream s;
33 // str = s << "We have " << num << " words";
34 str = str_stream() << "We have " << num << " words";
35
36 std::cout << str << std::endl;
37
38 return 0;
39 }
40

I changed the code by omitting line 34 (which is the original version
at that site) and adding
line 32 and 33. It can work correctly. Since that I haven't been
programming with C++ for
rather a long time, I need your help thirstily.

Thanks in advance.

Victor Bazarov

unread,
Feb 9, 2006, 9:54:13 PM2/9/06
to
David Lee wrote:
> I got the following code from
> http://builder.com.com/5100-6370_14-5079969.html,
> but it can't compile, neither can I figure out how to fix it. Anyone
> pls give me an
> explanation?
>
> 1 #include <string>

Please do not include line numbers like this. They prevent us from
simply copying the code from the message into a text editor and
compiling it. If you needed to refer to any line by its number, just
add a comment to that line indicating what its number is.

I ran your program as is (after stripping all those line numbers)
and it compiled and ran and output "We have 48 words<newline>".
Is that what you expected? I guess I am not sure what your problem
is. The code is fine.

V
--
Please remove capital As from my address when replying by mail


David Lee

unread,
Feb 9, 2006, 10:31:59 PM2/9/06
to
Hi, Victor Bazarov
Sorry for the inconvenience with line numbers attached.

Yes I want that output. I'm working on Fedora Core 4 with g++ 4.0.0,
and the compiler compliant that:

string.cc: In copy constructor ‘std::basic_ios<char,
std::char_traits<char> >::basic_ios(const std::basic_ios<char,
std::char_traits<char> >&)’:
/usr/lib/gcc/i386-redhat-linux/4.0.0/../../../../include/c++/4.0.0/bits/ios_base.h:779:
error: ‘std::ios_base::ios_base(const std::ios_base&)’ is
private
string.cc:34: error: within this context
string.cc: In copy constructor ‘std::basic_stringbuf<char,
std::char_traits<char>, std::allocator<char> >::basic_stringbuf(const
std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char>
>&)’:
/usr/lib/gcc/i386-redhat-linux/4.0.0/../../../../include/c++/4.0.0/streambuf:772:
error: ‘std::basic_streambuf<_CharT,
_Traits>::basic_streambuf(const std::basic_streambuf<_CharT, _Traits>&)
[with _CharT = char, _Traits = std::char_traits<char>]’ is
private
string.cc:34: error: within this context

Daniel T.

unread,
Feb 9, 2006, 10:36:57 PM2/9/06
to
In article <1139538914....@f14g2000cwb.googlegroups.com>,
"David Lee" <live...@gmail.com> wrote:

> Hi, all
> I got the following code from
> http://builder.com.com/5100-6370_14-5079969.html,
> but it can't compile, neither can I figure out how to fix it. Anyone
> pls give me an
> explanation?

Why do you think it can't compile? Did you maybe get an error from your
compiler? If so, then can we see it?

Thanks.


--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.

Victor Bazarov

unread,
Feb 9, 2006, 10:49:19 PM2/9/06
to
David Lee wrote:
> Hi, Victor Bazarov
> Sorry for the inconvenience with line numbers attached.

No biggie. Just don't make a habit out of it :*)

> Yes I want that output. I'm working on Fedora Core 4 with g++ 4.0.0,
> and the compiler compliant that:
>

> string.cc: In copy constructor â?~std::basic_ios<char,


> std::char_traits<char> >::basic_ios(const std::basic_ios<char,

> std::char_traits<char> >&)â?T:
> /usr/lib/gcc/i386-redhat-linux/4.0.0/../../../../include/c++/4.0.0/bits/ios_base.h:779:
> error: â?~std::ios_base::ios_base(const std::ios_base&)â?T is


> private
> string.cc:34: error: within this context

> string.cc: In copy constructor â?~std::basic_stringbuf<char,


> std::char_traits<char>, std::allocator<char> >::basic_stringbuf(const
> std::basic_stringbuf<char, std::char_traits<char>,
> std::allocator<char>

>> &)â?T:
> /usr/lib/gcc/i386-redhat-linux/4.0.0/../../../../include/c++/4.0.0/streambuf:772:
> error: â?~std::basic_streambuf<_CharT,


> _Traits>::basic_streambuf(const std::basic_streambuf<_CharT,
> _Traits>&)

> [with _CharT = char, _Traits = std::char_traits<char>]â?T is


> private
> string.cc:34: error: within this context

Well, I don't know what to tell you. Both VC++ v8 and Comeau C++ (online)
compile the code without a complaint. Try 'gnu.g++.help' or GNU online
forums. Perhaps there is a bug in 4.0 or in the library that ships with it.

Kai-Uwe Bux

unread,
Feb 9, 2006, 10:54:40 PM2/9/06
to
David Lee wrote:

In this line, you bind the temporary str_stream() to the non-const reference
parameter of operator<<( str_stream &, T const & ). This does not fly
because the standard forbids that.


> 35
> 36 std::cout << str << std::endl;
> 37
> 38 return 0;
> 39 }
> 40
>


Here is a fix:

#include <string>
#include <sstream>
#include <iostream>

class str_stream
{
public:

std::stringstream & underlying_stream() const

{ return m_streamOut; }

operator std::string() const
{
return m_streamOut.str();
}

str_stream & me ( void ) {
return ( *this );
}

private:
mutable std::stringstream m_streamOut;
};

template<class T>


const str_stream & operator<< (const str_stream & out, const T & value)

{
out.underlying_stream() << value;
return out;
}

int main() {
int num = 48;
std::string str;

str = str_stream().me() << "We have " << num << " words";



std::cout << str << std::endl;

return 0;
}


This compiles because it is legal to call a non-const member function of a
temporary object. The return value of me() is a reference, which can be
bound to the first parameter of operator<<(). That the reference just so
happens to refer to a temporary is immaterial.


Best

Kai-Uwe Bux

Kai-Uwe Bux

unread,
Feb 9, 2006, 11:14:39 PM2/9/06
to
Kai-Uwe Bux wrote:

Oops, sorry: I missed the const in operator<<(). BTW: that const is ill
advises logic and only serves to make the compiler shut up. The operation
is non-const!

[snip]


Best

Kai-Uwe Bux

David Lee

unread,
Feb 9, 2006, 11:27:39 PM2/9/06
to
Thanks a lot for kai-Uwe's explanation, and Bazarov, of course.
Thank you all. :)

Kai-Uwe Bux

unread,
Feb 9, 2006, 11:58:55 PM2/9/06
to
David Lee wrote:

I think I understand now what is going on. I stripped all of the example
down to:

#include <sstream>

struct str_stream {
mutable std::stringstream m_streamOut;
};

void dump ( str_stream const & out, int value ) {
out.m_streamOut << value;
}

int main() {
dump( str_stream(), 2 );
}


What happens is that according to clause [8.5.3/5] and implementation is
free to choose the mechanism by which to initialize const references from
things that are not lvalues. It may choose to

(a) directly bind to an rvalue, or
(b) copy construct a new temporary from the passed object and bind that.

Your implementation seems to opt for (b) which implies that you need a copy
constructor. However, stringstreams do not have those and you get a load of
error messages.

Now, what I do not understand is why this compiles on Comeau. The standard
mandates that the copy constructor be callable in any case. So, maybe my
analysis is mistaken.


Best

Kai-Uwe Bux

0 new messages