Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
299 views
in Technique[技术] by (71.8m points)

constants - What are C++ temporaries?

I was reading the constant chapter in Eckel and got mixed up in the part where Temporaries were explained . What I could get was that when we pass the reference to a function , the compiler creates a temporary which is a const object and so we can't modify it even if we pass a reference as

f(int &a){}

Now I tried to look at some other references for Temporaries online and got stuck up

http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr382.htm and

Are all temporaries rvalues in C++?

which prompted me that temporaries are much more than just passing references and creating const object for that inside the functions.Now I could get something out of these two links but could not say that I have understood the working , functionality and use of temporaries as a whole. It would be really helpful if someone could explain the concept of temporaries. Thanks in advance.
The original example of bruce eckel is:

// Result cannot be used as an lvalue
class X {
    int i;
    public:
    X(int ii = 0);
    void modify();
};
X::X(int ii) { i = ii; }
void X::modify() { i++; }
X f5() {
    return X();
}
const X f6() {
    return X();
}
void f7(X& x) { // Pass by non-const reference
    x.modify();
}
int main() {
    f5() = X(1); // OK -- non-const return value
    f5().modify(); // OK
    // Causes compile-time errors:
    //! f7(f5());
    //! f6() = X(1);
    //! f6().modify();
    //! f7(f6());
} ///:~
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

A temporary is an unnamed object (the results of some expressions), and is always an rvalue. Or perhaps one should better say that an expression which results in an rvalue is a temporary.

In C, rvalues/temporaries weren't really objects (in the sense the standard uses the word "object": something that is located in memory). Thus, for example, they weren't cv-qualified (an expression like 3 + 5 has type int, and not int const, and cv-qualifiers are ignored on function return values) and you can't take their address (because they aren't in memory, they don't have an address). In C++, the issue is clouded by class types: you can call a member function on an rvalue, and that member function will have a this pointer, which means that even rvalues (of class type) must have an address in memory, and that cv-qualifications have meaning, since if the return type is const, you can't call a non-const function on it.

In the end, although the concepts of rvalue and temporary are very closely related, the C++ standard uses the words in slightly different ways. The results of an expression are either an rvalue or an lvalue (C++11 adds other possibilities, but you can ignore them until you're an expert), and this distinction concerns all types. When the C++ standard speaks of a temporary, it is an rvalue which is (or has become) an object. For the most part, these have class type; there are very few cases where you would have a temporary which is not of class type in well written code, except where templates are involved. The distinction is important, because even if the built-in & operator is illegal on an rvalue, rvalues of class type have a defined "lifetime" and a memory address. That lifetime is until the end of the full expression. So when class types are concerned, the difference between a temporary and a named value is mainly that the temporary doesn't have a name, and it has a different lifetime. The lifetime of a class type is important for two reasons: first, it determines when the destructor is called, and second, if the object "leaks" a pointer to internal data, e.g. like std::string::c_str(), it determines how long this pointer may be valid.

Finally, I mention templates because that is about the only time you would have a const reference to a non-class type. The usual convention for in arguments is pass by value for non-class types, and by const reference for class types; the author of the template, however, doesn't know whether T will be a class types or not, and in most cases, will define his function to take a T const&. This will be, in practice, about the only time you'll end up with a temporary object of non-class type (and if the template saves the address of the argument, you may have problems).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...