コード例を次に示します。
#include <iostream>
class Foo
{
public:
explicit Foo(int x) : data(x) {};
Foo& operator++()
{
data += 1;
return *this;
}
void *get_addr()
{
return (void*)this;
}
friend Foo operator + (const Foo& lhs, const Foo& rhs);
friend std::ostream& operator << (std::ostream& os, const Foo& f);
private:
int data;
};
std::ostream& operator << (std::ostream& os, const Foo& f)
{
return (os << f.data);
}
Foo operator + (const Foo& lhs, const Foo& rhs)
{
return Foo(lhs.data + rhs.data);
}
void bar(Foo& f)
{
std::cout << "bar(l-value ref)" << std::endl;
}
void bar(const Foo& f)
{
std::cout << "bar(const l-value ref)" << std::endl;
}
void bar(Foo&& f)
{
std::cout << "bar(r-value ref)" << std::endl;
}
int main()
{
// getting the identity of the object
std::cout << Foo(5).get_addr() << std::endl; // Can write &Foo(5)
// by overloading &
// overload resolution
bar(Foo(5)); // prints r-value ref
// default copy assignment
std::cout << (Foo(78) = Foo(86)) << std::endl; // prints 86
// mutating operations
std::cout << (++Foo(5)) << std::endl; // prints 6
// more mutating operations
std::cout << (++(Foo(78) + Foo(86))) << std::endl; // prints 165
// overload resolution
bar((Foo(78) + Foo(86))); // prints r-value ref
}
Foo(5) のような式は prvalue ですか、それとも一般的な rvalue ですか? これらの式で get_addr() を呼び出すことができるという事実は、それらが同一性を持っていることを意味しますか? または、デフォルトの &-operator (オーバーロードされていないことを意味します) を適用できないという事実は、それらが ID を持たず、したがって prvalues であることを意味しますか?
それを生成した式を介して生成された値の可変性は、この値分類に直交していると言っても過言ではありませんか?