Creating mutually non-convertible yet identical classes

R

redqil

The problem I am facing is that an integer is the ideal representation
for many different classes I am using. I want to write overloaded
functions that are able to differentiate between the classes without
mutual interference. The naive, yet wrong, solution is:

typedef int A;
typedef int B;

void f(A a);
void f(B b); // Error

since typedef does not introduce a new type. In addition, I want the
naked expression "b = a" to error out during compile time.


The solution that I have implemented looks like this:

#define DECLARE_UNIQUE_CLASS_ALIAS(_ALIAS, _BASE)\
struct _ALIAS\
{\
_BASE value;\
_ALIAS(const _BASE& v)\
{\
this->value = v;\
}\
operator _BASE() const\
{\
return this->value;\
}\
};

DECLARE_UNIQUE_CLASS_ALIAS(A, int)
DECLARE_UNIQUE_CLASS_ALIAS(B, int)

This has the desired effect, but I am not happy with it because:
1. It uses macros, and is not debuggable.
2. Since the machine code for each alias is identical, and this will
be used a lot, this code will not be optimized by the compiler.

Could someone could suggest a solution that does not have the defects
that my code has?
 
V

Victor Bazarov

The problem I am facing is that an integer is the ideal representation
for many different classes I am using. I want to write overloaded
functions that are able to differentiate between the classes without
mutual interference. The naive, yet wrong, solution is:

typedef int A;
typedef int B;

void f(A a);
void f(B b); // Error

since typedef does not introduce a new type. In addition, I want the
naked expression "b = a" to error out during compile time.
[..]

Could someone could suggest a solution that does not have the defects
that my code has?

Use enums, maybe?

V
 
R

redqil

The problem I am facing is that an integer is the ideal representation
for many different classes I am using. I want to write overloaded
functions that are able to differentiate between the classes without
mutual interference. The naive, yet wrong, solution is:
typedef int A;
typedef int B;
void f(A a);
void f(B b); // Error
since typedef does not introduce a new type. In addition, I want the
naked expression "b = a" to error out during compile time.
[..]
Could someone could suggest a solution that does not have the defects
that my code has?

Use enums, maybe?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask- Hide quoted text -

- Show quoted text -

I think for some cases, enums will work fine. The problem with them is
that you are at the mercy of the compiler's internal representation of
enum. In particular, if the integral type to be overloaded is int64
and the compiler maxes enum out to 32 bit precision, the code will
fail.
Also, the enum solution only works for integers and can not be
generalized to any other type. I was hoping for some generic template,
non-macro based solution.
 
I

Ian Collins

The problem I am facing is that an integer is the ideal representation
for many different classes I am using. I want to write overloaded
functions that are able to differentiate between the classes without
mutual interference. The naive, yet wrong, solution is:

typedef int A;
typedef int B;

void f(A a);
void f(B b); // Error

since typedef does not introduce a new type. In addition, I want the
naked expression "b = a" to error out during compile time.
How about something like

template <typename T, typename V>
struct Unique
{
V value;

Unique( const V& value = V() ) : value(value) {}

operator V() const { return value; }
};

struct A_; typedef Unique<A_,int> A;
struct B_; typedef Unique<B_,int> B;

void f(A a);
void f(B b);

int main() {
A a;
B b;

a = 21; // OK
a = b; // Error
}
 
R

redblue

How about something like

template <typename T, typename V>
struct Unique
{
V value;

Unique( const V& value = V() ) : value(value) {}

operator V() const { return value; }

};

struct A_; typedef Unique<A_,int> A;
struct B_; typedef Unique<B_,int> B;

void f(A a);
void f(B b);

int main() {
A a;
B b;

a = 21; // OK
a = b; // Error

}

Thank you. This is precisely what I was looking for.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top