What's the difference between...

closed account (1yR4jE8b)
What's the difference between...
1
2
3
4
5
6
7

Foo bar();

//and

Foo bar = Foo();


I've noticed that when creating variables the 1st way, I sometimes get a wall of compilation errors that usually go away when I create them the second way. I thought they are supposed to be the same?
Last edited on
There is no difference.
What errors are you getting?
Last edited on
closed account (1yR4jE8b)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <class G>
std::ostream& operator<<(std::ostream& out, const ArrayList<G>& arrayList)
{
	std::stringstream buffer(); //for this
	buffer << "ArrayList[";

	for(typename ArrayList<G>::index_type i = 0; i < arrayList.size; ++i)
	{
		buffer << arrayList.data[i];
		if(i < (arrayList.size - 1))
			buffer << ", ";
	}
	buffer << "]";
	out << buffer.str();

	return out;
}


with compiler output:

1>------ Build started: Project: stringstreamtest, Configuration: Debug Win32 ------
1> main.cpp
1>c:\users\tyler\documents\visual studio 2010\projects\stringstreamtest\stringstreamtest\arraylist.h(149): error C2296: '<<' : illegal, left operand has type 'std::stringstream (__cdecl *)(void)'
1> c:\users\tyler\documents\visual studio 2010\projects\stringstreamtest\stringstreamtest\main.cpp(9) : see reference to function template instantiation 'std::ostream &operator <<<int>(std::ostream &,const ArrayList<T> &)' being compiled
1> with
1> [
1> T=int
1> ]
1>c:\users\tyler\documents\visual studio 2010\projects\stringstreamtest\stringstreamtest\arraylist.h(149): error C2297: '<<' : illegal, right operand has type 'const char [11]'
1>c:\users\tyler\documents\visual studio 2010\projects\stringstreamtest\stringstreamtest\arraylist.h(153): error C2296: '<<' : illegal, left operand has type 'std::stringstream (__cdecl *)(void)'
1>c:\users\tyler\documents\visual studio 2010\projects\stringstreamtest\stringstreamtest\arraylist.h(155): error C2296: '<<' : illegal, left operand has type 'std::stringstream (__cdecl *)(void)'
1>c:\users\tyler\documents\visual studio 2010\projects\stringstreamtest\stringstreamtest\arraylist.h(155): error C2297: '<<' : illegal, right operand has type 'const char [3]'
1>c:\users\tyler\documents\visual studio 2010\projects\stringstreamtest\stringstreamtest\arraylist.h(157): error C2296: '<<' : illegal, left operand has type 'std::stringstream (__cdecl *)(void)'
1>c:\users\tyler\documents\visual studio 2010\projects\stringstreamtest\stringstreamtest\arraylist.h(157): error C2297: '<<' : illegal, right operand has type 'const char [2]'
1>c:\users\tyler\documents\visual studio 2010\projects\stringstreamtest\stringstreamtest\arraylist.h(158): error C2228: left of '.str' must have class/struct/union
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========



I actually have 2 issues.

1. It only compiles with std::stringstream buffer = std::stringstream()
Note: this is ONLY with the Visual C++ Compiler.

2. It doesn't compile at all using G++, no matter how I write it.
#1: Foo bar();

This is a prototype to a function named 'bar' which takes no parameters and returns a Foo.

#2: Foo bar;

This creates a variable named 'bar' of type Foo, and calls the default constructor.

#3: Foo bar = Foo();

This is exactly almost the same as #2, but is more typing. (moorecm corrected me here, see his post)



Note that #1 is completely different.
Last edited on
Disch beat me :/
Last edited on
The second way is creating a nameless Foo and then is calling Foo's copy constructor to create bar.


I'm skeptical that this calls the copy ctor.

That'd be like saying int foo = 5; creates a nameless int before copying it to foo.
This was coined, by Scott Meyers in Effective C++, as C++'s most vexing parse:
Foo bar();
This is parsed by the compiler as a forward delcaration of a function bar that has no parameters and returns as Foo.

The following creates an instance of Foo named bar, which is often what you intended to do if you wrote the above:
Foo bar;

The following default constructs an instance of Foo named bar, similar to the above:
Foo bar = Foo();

However, in local scope, there is a difference between the last two examples. Built-in integral types will not be initialized in the former example but will be initialised to 0 in the latter.1

1 If I remember correctly, there is a scope where built-in types will be initialized to 0 using the former syntax. I want to say it is for globals, but I'm not certain... I'd have to look it up to be sure, so maybe someone who knows for sure can chime in with the details.
Last edited on
However, in local scope, there is a difference between the last two examples. Built-in integral types will not be initialized in the former example but will be initialised to 0 in the latter.


moorecm wins for bringing this up. I totally forgot about that.

*gives moorecm a cookie*
Actually, that may probably applies to floating point types and not just integral ones. I honestly don't know without either trying it or looking it up.
Last edited on
closed account (1yR4jE8b)
Also, I just fixed the compilation problem with g++ by declaring the stringstream like std::stringstream buffer;. Any idea why doesn't it compile when I write std::stringstream buffer = std::stringstream();
Last edited on
closed account (1yR4jE8b)
This is the wall of errors I get when I try to define buffer using std::stringstream buffer = std::stringstream();.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/ios_base.h: In copy constructor 'std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)':
In file included from c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/ios:39,
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/iosfwd:47:   instantiated from 'std::ostream& operator<<(std::ostream&, const ArrayList<T>&) [with G = int]'
main.cpp:13:   instantiated from here
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/ios_base.h:790: error: 'std::ios_base::ios_base(const std::ios_base&)' is private
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/iosfwd:47: error: within this context
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/iosfwd: In copy constructor 'std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(const std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)':
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/iosfwd:75: note: synthesized method 'std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)' first required here 
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/streambuf: 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> >&)':
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/iosfwd:63:   instantiated from 'std::ostream& operator<<(std::ostream&, const ArrayList<T>&) [with G = int]'
main.cpp:13:   instantiated from here
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/streambuf:770: error: 'std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>]' is private
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/iosfwd:63: error: within this context
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/iosfwd: In copy constructor 'std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(const std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)':
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/iosfwd:75:   instantiated from 'std::ostream& operator<<(std::ostream&, const ArrayList<T>&) [with G = int]'
main.cpp:13:   instantiated from here
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/iosfwd:75: note: synthesized method '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> >&)' first required here 
ArrayList.h: In function 'std::ostream& operator<<(std::ostream&, const ArrayList<T>&) [with G = int]':
In file included from main.cpp:5:
ArrayList.h:149: note: synthesized method 'std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(const std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)' first required here 
looks like jsmith was right.

std::stringstream buffer = std::stringstream(); creates a nameless stringstream, then copies that stringstream to buffer via the copy ctor.

This errors because the copy ctor in stringstream is private, and it's therefore illegal to do that.
looks like jsmith was right.

std::stringstream buffer = std::stringstream(); creates a nameless stringstream, then copies that stringstream to buffer via the copy ctor.

This errors because the copy ctor in stringstream is private, and it's therefore illegal to do that.


totally agree.. both are different..
Neat.
closed account (1yR4jE8b)
Ok, but if I try to compile

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <sstream>

int main()
{
	std::stringstream x = std::stringstream();
	std::stringstream y = std::stringstream(x);

	return 0;
}


Using Microsoft Visual C++ it compiles fine. Is this yet another example of Microsoft going against the standard?
That does not compile for me under MSVC 2008
Although this line on it's own will compile:
std::stringstream x = std::stringstream();
Last edited on
That does not compile for me under MSVC 2008
Although this line on it's own will compile:
std::stringstream x = std::stringstream();
i tried that too..



i don't know what compiler implements the ANSI/ISO standard..

this code compiles in Migw and not in VC++ 2008
1
2
3
4
5
6
7
8
#include <iostream>

int main()
{
    std::string game = "hello";
    std::cout << game << std::endl;
	return 0;
}


VC++ wants you to #include <string>
closed account (1yR4jE8b)
That does not compile for me under MSVC 2008
Although this line on it's own will compile:
std::stringstream x = std::stringstream();


I'm using Visual Studio 2010 RC, that might be the reason.
I think the Microsoft compiler programmer is being 'clever'
Although this looks like an assignment and would not normally be allowed.
std::stringstream x = std::stringstream();

All that is being done is the stringstream x is being initialised with the value of a default intialised
no-name stringstream.
So he/she probably thought 'What is the point of that' and just simply optimized it
to std::stringstream x;

On the other hand, he/she may have made a mistake :-)
Last edited on
closed account (1yR4jE8b)
While that may seem the case with

std::stringstream x = std::stringstream();

Strangely enough, if you have:

1
2
3
4

std::stringstream x = std::stringstream("initialString", std::ios_base::out | std::ios_base::in);
std::stringstream y = x;


The compiler allows it, but my program crashes and the debugger complains about heap corruption. This is actually pretty deal-breaking for me, non-standard behavior as well as bugs in the implementation...I think I'll just stick to GCC ;-P
Topic archived. No new replies allowed.