Archived

This topic is now archived and is closed to further replies.

Russell

Faking typedefs in C++

Recommended Posts

In C++ typedefs are not "strict", so I cannot do something like this:
typedef int Foo;
typedef int Bar;

bool valid (Foo f); // ambiguous
bool valid (Bar b); // ambiguous
If I want, I can write a class wrapper and overload operators as needed, and then I can have my validation functions all named valid(). That is what I have tried in the past, but I end up writing a lot of the same class wrapper code over and over again. Is there any way to make this so I can fake strict typedefs? I want to be able to create a type that can act like an int (or unsigned, short, long, char, etc.), but I can''t think of a way to do this. Maybe something with templates or inheritance? Any ideas?

Share this post


Link to post
Share on other sites
Define a templated wrapper class for your primitives. Due to a sudden deficit in imagination, I'll call it Wrapper. It goes something like:

class Magic {};

template <typename T, Magic & m>
class Wrapper {
public:
Wrapper() {}
Wrapper(T data) : data_(data) {}
// copy constructers, operator=, etc.

Wrapper & operator+=(const Wrapper & rhs) { data_ += rhs.data_; }
// other arithmetic operatoers, etc.

private:
T data_;
};

extern Magic FooMagic;
typedef Wrapper<int, FooMagic> Foo;
extern Magic BarMagic;
typedef Wrapper<int, BarMagic> Bar;

bool valid(Foo i);
bool valid(Bar j);

int main(int, char **) {
Foo i;
Bar j;

return 0;
}


edit: the key is that templates parameterized on different non type template parameters are separate types. So by using the symbols FooMagic and BarMagic, you can totally disambiguate the Wrapper types. No inheritance, so no slicing issues and no weird implicit conversions can make the compiler think that the two types are related.

edit: I can't spell today


[edited by - SiCrane on April 3, 2004 10:39:20 PM]

Share this post


Link to post
Share on other sites
I just wish to point out the importance of external linkage for the ''FooMagic'' and ''BarMagic'' reference parameters. That''s a template requirement.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
dunno why but you can try a prepo #define Foo int

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
dunno why but you can try a prepo #define Foo int


Definitely not. His problem is that he wants Foo and Bar to be treated as different types by the compiler even though they both are equivalent to int. Since the preprocessor does its substitution before the compiler ever sees the code, this cannot help it in any way, quite the opposite, in fact.


“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”
— Brian W. Kernighan

Share this post


Link to post
Share on other sites