Re: Trick to prevent conversion
On 11 Jan, 19:18, "Tom=E1s =D3 h=C9ilidhe" <t...@lavabit.com> wrote:
The problem is, that it's very easy to mistakenly take the value from
GetCurrentProcess and pass it as an argument to DoSomethingWithThread.
(I've done it already!). Therefore, I want two different types for these
identifiers, two types that can't convert to each other. At the moment I
have the following:
class Processor {
public:
struct ProcessHandle { unsigned i; };
struct ThreadHandle { unsigned i; };
ProcessHandle GetCurrentProcess(void);
ThreadHandle GetCurrentThread(void);
void DoSomethingWithProcess(ProcessHandle process_id);
void DoSomethingWithThread(ThreadHandle thread_id);
};
Of course, this does the trick. But I'm wondering if there's a more
elegant way of doing it? What other methods are there for making types
incompatible with each other?
I think this is a pretty good way of doing it. One way of making it
a bit more elegant/generic would be something like this
(warning - untested):
template <typename W, class TAG> class TypeWrapper {
W myWrapped;
public:
explicit TypeWrapper(W wrapped) : myWrapped(wrapped) {}
W getWrapped() { return myWrapped; }
};
#define TYPE_WRAPPER(W, X) \
struct X##Tag{}; \
typedef TypeWrapper<W, X##Tag> X
This could be in a generic header file, then you could say:
// define types ...
TYPE_WRAPPER(unsigned, ProcessHandle);
TYPE_WRAPPER(unsigned, ThreadHandle);
// use them
ProcessHandle ph(some_unsigned_var);
unsigned x = ph.getWrapped();
// etc but
ThreadHandle th = ph; // fails to compile