0%

Type safe handles in C++

看到這篇Type safe handles in C++覺得很有意思。原來可以這樣用。兩個同樣type,不過代表不同意義的Handle,要怎麼區別才安全。

Tag solution

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
template<class Tag, class impl, impl default_value>
class ID
{
public:
static ID invalid() { return ID(); }

// Defaults to ID::invalid()
ID() : m_val(default_value) { }

// Explicit constructor:
explicit ID(impl val) : m_val(val) { }

// Explicit conversion to get back the impl:
explicit operator impl() const { return m_val; }

friend bool operator==(ID a, ID b) { return a.m_val == b.m_val; }
friend bool operator!=(ID a, ID b) { return a.m_val != b.m_val; }

private:
impl m_val;
};
struct sound_tag{};
typedef ID<sound_tag, int, -1> sound_id;
struct sprite_tag{};
typedef ID<sprite_tag, int, -1> sprite_id;

Strong typedef

根據未來的C++ Proposal Toward Opaque Typedefs for C++1Y,用Boost_StrongTypedef可以達到類似的效果

1
2
3
4
5
#include <boost/serialization/strong_typedef.hpp>
BOOST_STRONG_TYPEDEF(int, sound_id);
BOOST_STRONG_TYPEDEF(int, sprite_id);
sprite_id gfx = create_sprite();
destroy_sound(gfx); // ERRROR!