Re: Why extracting string from stringstream(a) fails?
On 26/10/09 17:47, James Kanze wrote:
On Oct 26, 4:07 pm, Maxim Yegorushkin<maxim.yegorush...@gmail.com>
wrote:
Alf P. Steinbach wrote:
* Maxim Yegorushkin:
On 25/10/09 18:13, Johannes Schaub (litb) wrote:
Maxim Yegorushkin wrote:
Here is another trick to turn a temporary into an
l-value, so that any operator>> can work on a temporary
stream object:
template<class T>
inline T& lvalue(T const& t) {
return const_cast<T&>(t);
}
Although this will be ill-formed because it requires the
stream to have a copy constructor.
Interesting.
My understanding is that a copy constructor is only
required when copy initialization is involved or when a
conversion is made to initialize a function argument. In
this case there is no copy initialization or conversion
happening. Therefore, the code must be well formed.
Could you elaborate you point please?
It's different in C++98 and C++0x (C++03 is just C++98 with
corrections).
The argument passing is defined as copy initialization. And
in C++98 the implementation is allowed to make any number of
copies of an rvalue actual argument passed to 'T const&'
formal argument, or for any copy initialization. Which means
that the type must provide a suitable copy constructor. For
example, that means that you can't do this thing with a
std::auto_ptr. Or a stream.
Even more interesting.
Given the following declaration:
void foo(int& ref);
Could you explain how ref argument can possibly be
copy-initialized please?
There's more to it that Alf revealed. (It wouldn't be the C++
standard if it were that simple.) It's copy initialization, so
the rules for copy initialization apply. The rule that requires
a copy constructor when copy initialization is used only applies
when initializing a reference with an rvalue (and this is the
only time copies are allowed). If the initializer is an lvalue,
everything is fine---otherwise, things like:
int i;
int& ri = i;
would have somewhat unexpected semantics.
I've been looking at 8.5 Initializers now. My understanding is that
because that form of initialization which is used for function arguments
is called copy initialization, it implies that a copy constructor is
required regardless of whether an argument is a reference that can be
bound directly. It also says that copy elision is a permissible
optimization, but does not require it.
My intuitive expectation is that implied by the spirit of C++: you don't
pay for what you don't use. Applied to the initialization of reference
function arguments I would expect it to require the copy constructor
only when it is actually used. Oh, well ;)
Alf and Johannes report that initialization of references does not
require a copy constructor in the C++0x standard. I am glad that they
elaborated this case :)
--
Max