Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declare types without implicit conversion in C++

Tags:

c++

I want to declare my own numeric types, exactly like unsigned int, but I do not want the types to be implicitly converted. I tried this first: typedef unsigned int firstID; typedef unsigned int secondID;

but this is no good as the two types are just synonyms for unsigned int, so are freely interchangable.

I'd like this to cause an error:

firstID fid = 0;
secondID sid = fid; // no implicit conversion error

but this to be okay:

firstID fid = 0;
secondID sid = static_cast<secondID>(fid); // no error

My reason is so that function arguments are strongly typed, eg:

void f( firstID, secondID ); // instead of void f(unsigned int, unsigned int)

What is the mechanism I am looking for?

Thanks

Si

like image 247
sipickles Avatar asked Feb 04 '10 13:02

sipickles


People also ask

Does C have implicit type conversion?

Overview. Implicit type conversion in C language is the conversion of one data type into another datatype by the compiler during the execution of the program. It is also called automatic type conversion.

Which type of conversion is not possible in C?

Which type of conversion is NOT accepted? Explanation: Conversion of a float to pointer type is not allowed.

Can you convert data types in C?

Type Casting is basically a process in C in which we change a variable belonging to one data type to another one. In type casting, the compiler automatically changes one data type to another one depending on what we want the program to do.

How many types of type conversion are there in C?

The two types of type casting in C are: Implicit Typecasting. Explicit Typecasting.


2 Answers

Maybe BOOST_STRONG_TYPEDEF form boost/strong_typedef.hpp would help.

like image 89
Alexander Poluektov Avatar answered Oct 18 '22 06:10

Alexander Poluektov


As you noted: typedef is badly named (it should be typealias (D has explicitly added typealias (last time I looked))

So the only way you can do this is to create two unique classes.
I am not going to say you can't write a specialization of static_cast<> to do what you want, but I think (and I have not put that much thought into it yet) doing so would be a bad idea (even if it legal), I think a better approach is to have each class constructor use unsigned int that are explicit (so there is no auto conversion).

 struct FID
 {
     explicit FID(unsigned int v): value(v) {}
     operator unsigned int() {return value;}
     unsigned int value;
 };

 class SID {/* Stuff */};

 FID   fid(1U);
 SID   sid(2U);

 doSomthingWithTwoSID(sid,SID(static_cast<unsigned int>(fid));

Making the constructor explicit means no auto conversion between types.
By adding the built in cast operator to unsigned int means that it can be used anywhere an int is expected.

like image 40
Martin York Avatar answered Oct 18 '22 06:10

Martin York