Re: Constness of return-by-value temporaries
On Mon, 8 May 2006 10:37:38 CST, "Tom1s" <NULL@NULL.NULL> wrote:
It's perfectly legitimate to use "const_cast", and subsequently alter an
object, but only if the object was defined as non-const in the first place.
Example 1:
#include <string>
void Func( const std::string &cstr )
{
std::string &str = const_cast<std::string&>(cstr);
str += "monkey";
}
int main()
{
std::string str("ape");
Func(str);
}
I've seen many examples of where a temporary object is non-const. Example 2:
#include <string>
#include <vector>
std::vector<std::string> Func()
{
std::vector<std::string> vec;
vec.push_back("One");
vec.push_back("Two");
return vec;
}
int main()
{
Func().push_back("Three"); // <-- Non-const member function
}
(I'll admit that I'm not certain if ALL temporaries are non-const throughout
the entire language. Could someone please clarify that?)
Since it is possible to return either a const OR non-const object from
a function, I would say this is not true. However, AFAIK, all
temporaries returned from a function are rvalues, whether or not they
are const (NOTE: const objects which are not temporaries are lvalues
because you can take their address. I believe that this is one of the
ways to distinguish between the two, although I am not 100% sure --
and I don't have time to look up chapter and verse in the C++ standard
bible at the moment. ;)
We can use a const reference to "extend the lifetime" of a temporary
returned-by-value from a function. Example 3:
#include <string>
#include <vector>
std::vector<std::string> Func()
{
std::vector<std::string> vec;
vec.push_back("One");
vec.push_back("Two");
return vec;
}
int main()
{
const std::vector<std::string> &cvec = Func();
std::string str( cvec.at(0) );
str += "monkey";
}
We saw in Example 2, that the temporary object returned-by-value from
"Func" was non-const.
But it is nevertheless an rvalue...
I have a question, which I have asked on comp.lang.c++, but which no-one has
seemed willing to answer. Is the following translation unit well-formed, and
absent of undefined behaviour?
#include <string>
using std::string;
#include <vector>
using std::vector;
vector<string> Func()
{
vector<string> vec;
vec.push_back("One");
vec.push_back("Two");
return vec;
}
#include <iostream>
using std::cout; using std::endl;
You need to inclue <ostream> as well in order to conform to the
standard if you are using std::endl.
int main()
{
const vector<string> &cvec = Func();
vector<string> &vec = const_cast< vector<string>& >(cvec);
vec.push_back("Three");
cout << vec.at(0) << endl
<< vec.at(1) << endl
<< vec.at(2) << endl;
}
-Tom1s
const_cast *can* invoke undefined behavior. Did you read 5.2.11 very
carefully?
As I see it, the problem is that all the code within the main()
function must be seen in light of the fact that Func() might just as
well return a const reference, in which case the two const_casts
*would* invoke UDB.
--
Bob Hairgrove
NoSpamPlease@Home.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]