// ------------------
// RValueVsLValue.c++
// ------------------

#include <cassert>  // assert
#include <iostream> // cout, endl
#include <string>   // string

struct A {
    std::string f () {
        return "A::f";}

    std::string fc () const {
        return "A::fc";}};

std::string g (A&) {
    return "g";}

std::string gc (const A&) {
    return "gc";}

A& hr () {
    static A x;
    return x;}

const A& hrc () {
    static A x;
    return x;}

A hv () {
    return A();}

const A hvc () {
    return A();}

int main () {
    using namespace std;
    cout << "RValueVsLValue..c++" << endl;

    // x is an l-value
    {
    A x;
    assert(x.f()  == "A::f");
    assert(x.fc() == "A::fc");
    assert(g(x)   == "g");
    assert(gc(x)  == "gc");
    }

    // A() is an r-value
    {
    assert(A().f()  == "A::f");    // ?
    assert(A().fc() == "A::fc");
//  assert(g(A())   == "g");       // doesn't compile
    assert(gc(A())  == "gc");
    }

    // hr() returns an l-value
    {
    assert(hr().f()  == "A::f");
    assert(hr().fc() == "A::fc");
    assert(g(hr())   == "g");
    assert(gc(hr())  == "gc");
    }

    // hrc() returns an r-value
    {
//  assert(hrc().f()  == "A::f");   // doesn't compile
    assert(hrc().fc() == "A::fc");
//  assert(g(hrc())   == "g");      // doesn't compile
    assert(gc(hrc())  == "gc");
    }

    // hv() returns an r-value
    {
    assert(hv().f()  == "A::f");   // ?
    assert(hv().fc() == "A::fc");
//  assert(g(hv())   == "g");      // doesn't compile
    assert(gc(hv())  == "gc");
    }

    // hvc() returns an r-value
    {
//  assert(hvc().f()  == "A::f");  // doesn't compile
    assert(hvc().fc() == "A::fc");
//  assert(g(hvc())   == "g");     // doesn't compile
    assert(gc(hvc())  == "gc");
    }

    cout << "Done." << endl;
    return 0;}


syntax highlighted by Code2HTML, v. 0.9.1