1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
#include <iostream>
#include <utility>
#include <limits>
struct point
{
constexpr point( std::pair<int,int> location ) : location(location) {}
constexpr std::pair<int,int> where() const { return location ; }
void move_to( std::pair<int,int> pt ) { location = pt ; }
private: std::pair<int,int> location ;
};
// constexpr: object is a constant expression evaluated at compile time, implicitly const at run time
// this object can't be modified through *any* interface at run time
// this object is treated as a compile-time constant object
constexpr point here( { std::numeric_limits<int>::max(), sizeof(int) } ) ;
// const: immutable at runtime, may or may not be evaluated at compile time
// this object can't be modified through *any* interface at run time
const point there( { 100, 100 } ) ;
// not const qualified: therefore mutable; but we can still create
// an interface to the object through which the object can't be modified
point somewhere( here.where() ) ;
// can't modify the object through this interface;
// though it may well be modifiable through other interfaces
const point& a = somewhere ;
// function must be evaluated at compile time if actual arguments are constant extressions
template < typename T, std::size_t N >
constexpr std::size_t foo( T(&)[N], point pt ) { return N + pt.where().first ; }
// can't modify the object through the interface p;
// it may or may not be modifiable through other interfaces
int bar( const point& p )
{
return p.where().first ;
// p.move_to( { 0, 0 } ) ; // can't do this
// here.move_to( { 0, 0 } ) ; // can't do this; here is a const object
// there.move_to( { 0, 0 } ) ; // can't do this; there is a const object
somewhere.move_to( { 0, 0 } ) ; // fine, even if p aliases somewhere
}
int main()
{
// constant expression evaluated at compile time
constexpr double array[ here.where().first > 4 ? here.where().second : 74 ] {} ;
constexpr auto sz = foo(array,here) ;
const auto a = there.where() ; // immutable at run time
auto b = somewhere.where() ; // not const qualified
const auto& c = b ; // create an interface through which c can't be modified
struct person
{
person( std::string name ) : name(name) {}
// ***
const std::string name ; // logically const, can't be modified at run time
// const in const qualified objects, modifiable in modifiable objects
std::string mail ;
// an implementation detail that does not represent
// the visible logical state of the object; modifiable in any object
private: mutable int impl_detail ;
};
}
|