// Boost.TypeErasure library // // Copyright 2011 Steven Watanabe // // Distributed under the Boost Software License Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // $Id$ #include #include #include #include #include #include #include namespace mpl = boost::mpl; using namespace boost::type_erasure; void references1() { //[references1 /*` To capture by reference, we simply add a reference to the __placeholder. */ int i; any, _self&> x(i); any_cast(x) = 5; // now i is 5 /*` [note `_self` is the default __placeholder, so it is easiest to use `_self&`. We could use another __placeholder instead. __any`<`__typeid_`<_a>, _a&>` has exactly the same behavior.] */ //] } void references2() { //[references2 /*` References cannot be rebound. Just like a built-in C++ reference, once you've initialized it you can't change it to point to something else. `` int i, j; any, _self&> x(i), y(j); x = y; // error `` [note As with any other operation, `x = y` for references acts on `i` and `j`. Assignment like this is legal if __assignable`<>` is in the Concept, but `x` would still hold a reference to `i`.] */ //] } void references3() { //[references3 /*` A reference can be bound to another __any. */ typedef mpl::vector< copy_constructible<>, incrementable<> > requirements; any x(10); any y(x); ++y; // x is now 11 //] } void references4() { //[references4 /*` If a reference is used after the underlying object goes out of scope or is reset, the behavior is undefined. */ typedef mpl::vector< copy_constructible<>, incrementable<>, relaxed > requirements; any x(10); any y(x); x = 1.0; ++y; // undefined behavior. //] } void references5() { typedef mpl::vector< copy_constructible<>, incrementable<> > requirements; //[references5 /*` This only applies when a reference is constructed from a value. If a reference is constructed from another reference, the new reference does not depend on the old one. */ any x(10); boost::shared_ptr > p( new any(x)); any y(*p); // equivalent to y(x); p.reset(); ++y; // okay //] } void references6() { //[references6 /*` Both const and non-const references are supported. */ int i = 0; any, _self&> x(i); any, const _self&> y(x); /*` A reference to non-const can be converted to a reference to const, but not the other way around. Naturally, we can't apply mutating operations to a const reference. any, _self&> z(y); // error ++y; // error */ //] } //[references //` (For the source of the examples in this section see //` [@boost:/libs/type_erasure/example/references.cpp references.cpp]) //` [references1] //` [references2] //` [references3] //` [references4] //` [references5] //` [references6] //]