temporary and unnamed objects

A

Austin

class String {
public:
String(const char* = "");
...
};

void print_heading(String)
....
print_heading("Annual Report");

I know that this call will invoke an implicit conversion, as the compiler
will write:

String temp("Annual Report");
print_heading(temp) //-> the temp object will be destoryed here

How about if I call the function using a unnamed object:

print_heading(String("Annual Report"))

My question is when the unnmaed object will be destroy? It will be
destroyed after the function all or the end of a local scope?

Thanks in advance.
 
J

James Kanze

class String {
public:
String(const char* = "");
...
};
void print_heading(String)
...
print_heading("Annual Report");
I know that this call will invoke an implicit conversion, as the compiler
will write:
String temp("Annual Report");
print_heading(temp) //-> the temp object will be destoryed here
How about if I call the function using a unnamed object:
print_heading(String("Annual Report"))
My question is when the unnmaed object will be destroy? It will be
destroyed after the function all or the end of a local scope?

There are a few exceptions, but generally, temporaries are
destroyed at the end of the full expression in which they were
created. It doesn't matter whether the temporary was the result
of an implicit conversion (as in your first example) or an
explicit conversion (as in the second) or from any other source
(function return value, etc.).
 
S

sagenaut

There are a few exceptions, but generally, temporaries are
destroyed at the end of the full expression in which they were
created. It doesn't matter whether the temporary was the result
of an implicit conversion (as in your first example) or an
explicit conversion (as in the second) or from any other source
(function return value, etc.).

I think that the unnamed object in the second case is treated as auto
allocated in the stack. It will not be destroyed at the end of the
full expression, rather, it will be destroyed at the end of the local
scope where the unnamed object is created.
 
S

Salt_Peter

class String {
public:
String(const char* = "");
...

};

void print_heading(String)
...
print_heading("Annual Report");

I know that this call will invoke an implicit conversion, as the compiler
will write:

String temp("Annual Report");
print_heading(temp) //-> the temp object will be destoryed here

How about if I call the function using a unnamed object:

print_heading(String("Annual Report"))

My question is when the unnmaed object will be destroy? It will be
destroyed after the function all or the end of a local scope?

At end of local scope (print_heading(...)'s scope). However, we don't
know _how_ you are storing the literal string or any pointer/reference
to it. This is relevant here since you are passing that String by
value (don't do that). Any time you are passing parameters that are
not primitives, prefer a reference_to_constant.

void print_heading(const String& s) { }

As a suggestion, if you prefer not using std::string, how does a
std::vector< char > sound like?
Observe the lifetime of the temporary below, the fact that it exists
throughout the function's scope is guarenteed by the standard (binding
a reference_to_constant).
This toy String stores the terminator, which may _not_ be what you
want.

#include <iostream>
#include <ostream>
#include <iterator>
#include <vector>

template< typename T = char >
class String
{
std::vector< T > vt;
public:
// def ctor
String() : vt() { }
// parametized array ctor
template< const std::size_t Size >
String(const T(& array)[Size])
: vt(&array[0], &array[Size])
{
std::cout << "String(array)\n";
}
~String() { std::cout << "~String()\n"; }
// member functions
std::size_t size() const { return vt.size(); }
// friend op<<
friend
std::eek:stream& operator<<(std::eek:stream& os, const String< T >& s)
{
std::copy( s.vt.begin(),
s.vt.end(),
std::eek:stream_iterator< T >(os) );
return os;
}
};

void foo(const String<char>& s)
{
std::cout << "foo(const String&)\n";
}

int main()
{
{ // anonymous scope
String<> s("a short string");
std::cout << s << std::endl;
foo(s);
}

std::cout << "about to generate temporary...\n";
foo(String<>("a local string"));
std::cout << "back in main...\n";
}

/*
String(array)
a short string
foo(const String&)
~String() // end of anon scope

about to generate temporary...
String(array) // temp
foo(const String&) // foo body
~String() // end of local scope
back in main...
*/
 
J

James Kanze

I think that the unnamed object in the second case is treated as auto
allocated in the stack. It will not be destroyed at the end of the
full expression, rather, it will be destroyed at the end of the local
scope where the unnamed object is created.

Which second case are you talking about? I ignored the code with
the explicit variable "temp" when counting, because there is no
"temporary" in that code, only a named variable. Named
variables have, of course, the lifetime that the standard says
they have; if the variable is of auto storage duration, it will
be destroyed when it goes out of scope, and not before (nor
after). In the first and last case (the second where there is a
temporary), the temporary will be destroyed at the end of the
full expression. According to the standard, the only cases
where a destructor of a temporary (an unnamed object) will be
called other than at the end of the full expression are when the
temporary is the default argument to a constructor of an array
element, and when it is used to initialize a reference, neither
of which applies here. (If the parameter of print_heading were
std::string const&, the rules concerning initialization of a
reference would apply. But those rules make a special case if
the reference is a function parameter, reverting the lifetime to
the end of the full expression. More generally, the rules
concerning the lifetime of a temporary used to initialize a
reference will never shorten the lifetime to less than the end
of the full expression.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top