Re: Is this kosher?
On Aug 27, 8:24 pm, Tim H <thoc...@gmail.com> wrote:
I should have asked this better, I was in a rush. Sorry
On Aug 27, 8:22 am, Tim H <thoc...@gmail.com> wrote:
class Foo {};
template <typename Tdata>
const Foo &operator<<(const Foo &foo, const Tdata &data)
{
std::cout << "FOO: " << data << std::endl;
}
This code works:
Foo() << "string";
This code seems to work:
Foo() << "string" << 99 << "other" << "more";
Is the temporary Foo guaranteed to exist until the end of this
full statement, or can the temporary possibly go away
somewhere in the middle?
The temporary is guaranteed to last until the end of the full
expression, in this case, until the end of the statement.
This code works, and returns a valid Foo.
Foo MyFunction1()
{
return Foo();
}
Is this guaranteed to only construct one Foo? Or can the
compiler optionally construct a local Foo and then copy
construct the returned Foo in caller's scope?
The formal semantics are for it to construct a temporary Foo,
then copy construct it for the return. The compiler is
explicitly allowed to elide the copy, however, even if it has
side effects. Whoever uses the return value is likely to have
to copy construct it as well, formally; again, in certain
contexts, the compiler is allowed to elide the copy.
Note that even if the compiler does elide the copy, the copy
must be legal.
This code works, and returns a valid Foo.
Foo MyFunction2()
{
return Foo() << "MyFunction1";
}
As I understand, it returns a copy of the temporary Foo,
right?
Almost certainly, since all it has to return is a reference, and
not an object (with known lifetime, etc.).
Meaning that the Foo constructor will be called twice
(for two seperate instances).
Two different constructors will be called; the default
constructor and the copy constructor.
How about this?
const Foo &MyFunction3()
{
return MyFunction1();
}
That's a good recepe for undefined behavior. You're returning a
reference to a temporary object, which will be destructed before
the return.
Or this?
const Foo &MyFunction4()
{
return MyFunction1() << "something" << "else";
}
Both of those are returning references to temporaries, right?
Right.
Yet the compiler did not complain. Both of these are illegal,
as I understand. The temporary values do not have their
lifetime extended, am I correct?
Correct. It's undefined behavior, so the compiler is not
required to complain. In the second case, supposing separate
compilation and a non-inlined operator<<, it's difficult to see
how it could detect the error to begin with.
Are you trying to do something specific, or are these just
general questions? Some of your code looks very much like my
logging objects; the solution here will be an rvalue reference,
once the next version of the standard is adopted and
implemented. Until then, it can be simulated using reference
counting, implementing copy so that all copied instances are
idempotent, and destruction so that only the destructor of the
last copied instance does whatever is critical.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34