By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,248 Members | 882 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,248 IT Pros & Developers. It's quick & easy.

Why this code can't compile?

P: n/a
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.

Feb 10 '06 #1
Share this Question
Share on Google+
8 Replies


P: n/a
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.
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.


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
Feb 10 '06 #2

P: n/a
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

Feb 10 '06 #3

P: n/a
In article <11*********************@f14g2000cwb.googlegroups. com>,
"David Lee" <li*******@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.
Feb 10 '06 #4

P: n/a
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.

V
--
Please remove capital As from my address when replying by mail
Feb 10 '06 #5

P: n/a
David Lee 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?

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";
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
Feb 10 '06 #6

P: n/a
Kai-Uwe Bux wrote:
David Lee 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?

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";


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.


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
Feb 10 '06 #7

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

Feb 10 '06 #8

P: n/a
David Lee 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?

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 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
Feb 10 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.