Best way to abuse exceptions

Pages: 12
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 ;
    };
}
Topic archived. No new replies allowed.
Pages: 12