Distinct sub-types of POD?

J

Joseph Turian

How can I create distinct sub-types of some POD?

Let me clarify:

If I do the following:
typedef unsigned T1;
typedef unsigned T2;
then I have types T1 and T2.
However, there is no type safety, and T1 and T2 can be used
interchangeably.
So this is not a viable solution, because I don't want a T1 to be
passed to a function that wants a T2.

A solution that does work, if I'm not mistaken, is to define a class T1
that stores the POD but only defines the member functions with respect
to other T1 objects. Then, duplicate that code, and s/T1/T2/g.
The problem with this solution is that if I want to create twenty
distinct types, that requires a lot of redundant code.

Is there a clean, simple way to do what I'm describing, without code
copying?

Thanks,
Joseph
 
J

Jonathan Mcdougall

Joseph said:
How can I create distinct sub-types of some POD?

Let me clarify:

If I do the following:
typedef unsigned T1;
typedef unsigned T2;
then I have types T1 and T2.
However, there is no type safety, and T1 and T2 can be used
interchangeably.

Yes. These are not new types.
So this is not a viable solution, because I don't want a T1 to be
passed to a function that wants a T2.

A solution that does work, if I'm not mistaken, is to define a class T1
that stores the POD but only defines the member functions with respect
to other T1 objects. Then, duplicate that code, and s/T1/T2/g.
The problem with this solution is that if I want to create twenty
distinct types, that requires a lot of redundant code.

Is there a clean, simple way to do what I'm describing, without code
copying?

Yes, use templates.

template <class T, int>
class Wrapper
{
private:
T t_;
};

typedef Wrapper<unsigned int, 1> T1;
typedef Wrapper<unsigned int, 2> T2;

Wrapper does not use its second template parameter, it is only there to
create a distinct type. Just make sure to give them different ids. I
could not think quickly of a way to automate the id creation.


Jonathan
 
A

anujanujdhamija

I tried following:

/*************************************************************/
#include <iostream>

using namespace std;
class base
{
public:

int i;
base(int l):i(l){}
void setInt(int k) { i = k; }
int getInt() { return i; }
//cant overload operator int() as it will allow comparison btw
subtypes

/*Other methods*/
};

class T1:public base
{
public:
T1(int j):base(j){}
};

class T2:public base
{
public:
T2(int k):base(k){}
};

//Function expecting T1
void func(T1 t)
{
}

int main()
{
T1 t1 = 5;
T2 t2 = 6;

//Invoke func with T2
func(t2); //error: conversion from `T2' to non-scalar type `T1'
requested
}

/*************************************************************/

So only code you need with each derived type is the constructor that
too if you need initialization like: "T1 t1 = 5;"
 
M

Marcus Kwok

#include <iostream>

using namespace std;
class base
{
public:

int i;
base(int l):i(l){}
void setInt(int k) { i = k; }
int getInt() { return i; }
//cant overload operator int() as it will allow comparison btw
subtypes

/*Other methods*/
};

class T1:public base
{
public:
T1(int j):base(j){}
};

class T2:public base
{
public:
T2(int k):base(k){}
};

//Function expecting T1
void func(T1 t)
{
}

int main()
{
T1 t1 = 5;
T2 t2 = 6;

//Invoke func with T2
func(t2); //error: conversion from `T2' to non-scalar type `T1'
requested
}

This may not be an issue for the OP, but with the above, someone could
write a function

void func(base* b);

and can call it with both

func(&t1);
func(&t2);
 

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,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top