Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old February 10th, 2006, 02:45 AM
David Lee
Guest
 
Posts: n/a
Default Why this code can't compile?

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.

  #2  
Old February 10th, 2006, 03:05 AM
Victor Bazarov
Guest
 
Posts: n/a
Default Re: Why this code can't compile?

David Lee wrote:[color=blue]
> 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>[/color]

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.
[color=blue]
> 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.[/color]

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


  #3  
Old February 10th, 2006, 03:45 AM
David Lee
Guest
 
Posts: n/a
Default Re: Why this code can't compile?

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>[color=blue]
>&)’:[/color]
/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

  #4  
Old February 10th, 2006, 03:45 AM
Daniel T.
Guest
 
Posts: n/a
Default Re: Why this code can't compile?

In article <1139538914.621718.66700@f14g2000cwb.googlegroups. com>,
"David Lee" <live4thee@gmail.com> wrote:
[color=blue]
> 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?[/color]

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.
  #5  
Old February 10th, 2006, 04:05 AM
Victor Bazarov
Guest
 
Posts: n/a
Default Re: Why this code can't compile?

David Lee wrote:[color=blue]
> Hi, Victor Bazarov
> Sorry for the inconvenience with line numbers attached.[/color]

No biggie. Just don't make a habit out of it :*)
[color=blue]
> 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>[color=green]
>> &)â?T:[/color]
> /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[/color]

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.

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


  #6  
Old February 10th, 2006, 04:15 AM
Kai-Uwe Bux
Guest
 
Posts: n/a
Default Re: Why this code can't compile?

David Lee wrote:
[color=blue]
> 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";[/color]

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.

[color=blue]
> 35
> 36 std::cout << str << std::endl;
> 37
> 38 return 0;
> 39 }
> 40
>[/color]


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
  #7  
Old February 10th, 2006, 04:25 AM
Kai-Uwe Bux
Guest
 
Posts: n/a
Default Re: Why this code can't compile?

Kai-Uwe Bux wrote:
[color=blue]
> David Lee wrote:
>[color=green]
>> 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";[/color]
>
> 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.[/color]

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
  #8  
Old February 10th, 2006, 04:35 AM
David Lee
Guest
 
Posts: n/a
Default Re: Why this code can't compile?

Thanks a lot for kai-Uwe's explanation, and Bazarov, of course.
Thank you all. :)

  #9  
Old February 10th, 2006, 05:15 AM
Kai-Uwe Bux
Guest
 
Posts: n/a
Default Re: Why this code can't compile?

David Lee wrote:
[color=blue]
> 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
>[/color]

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
 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles