Reputation: 8182
I would like to use something like typedef in my C++ programs to enhance type safety.
As an example, suppose I have two functions
void function1(unsigned idOfType1);
void function2(unsigned idOfType2);
then I can mistakenly pass idOfType2 to function1 and vice versa. I want the compiler to give me an error in this case. I am aware that I could wrap these unsigned in a struct, but then I'd have to give provide a field name and use .
to access them, which is slightly inconvenient. Is there a good way around this?
Edit: As far as I know typedef
will not work for this purpose as it is just a shorthand for a type and will not be used for type checking.
Upvotes: 17
Views: 7414
Reputation: 1761
In foonathan's blog post from 2016 various approaches are covered, starting with an example class for simple cases:
class meter
{
public:
explicit meter(int val)
: value_(val) {}
explicit operator int() const noexcept
{
return value_;
}
private:
int value_;
};
and ending with a short template library with arithmetic support for custom type-safe types, allowing one to write this:
struct meter
: strong_typedef<meter, int>, addition<meter>
{
using strong_typedef::strong_typedef;
};
Upvotes: 0
Reputation: 279255
Use Boost strong typedef:
typedef
creates an alias for an existing type. It does not create a new type that can be used for matching either function or template parameters...Usage of BOOST_STRONG_TYPEDEF addresses this...
BOOST_STRONG_TYPEDEF
is a macro which generates a class named "name" wraps and instance of its primitive type and provides appropriate conversion operators in order to make the new type substitutable for the one that it wraps.
Upvotes: 15
Reputation: 2569
This is a late reply to an old question. But there are new developments on the C++ front and for the sake of completeness I'm adding this answer:
The opaque_typedef library is the author's attempt to provide most of the value of opaque typedefs through a library, without waiting for opaque typedefs to become a language feature.
The author of this library, Kyle Markley had a short brilliant speech at the cppcon 2015 introducing this library. The slides of his speech are on github the source code of the library is available on sourceforge. The library is header-only, written in C++11. Gcc and clang are ok, but VS2015 seems to have problems with it.
The use of the library is straight-forward. The following code was taken from the documentation. It creates an opaque typedef of int. It has the same interface as an int (it can be added, shifted, incremented, compared, etc.) but the arguments and return values are of the newly-created type, not of int:
#include "opaque/numeric_typedef.hpp"
struct myint : opaque::numeric_typedef<int, myint> {
using base = opaque::numeric_typedef<int, myint>;
using base::base;
};
Upvotes: 1
Reputation: 404
You can check the type in your function, so that if it didn't match, you can print an error or something.
You can use typeid to detect variable type, as follows:
typeid(*variablename*).name()
As suggested in one of the answers here, this is compiler-dependent and you have to use try-and-error method to find out which value works for you.
Upvotes: -3
Reputation: 40947
As you say, a typedef won't help you here. I can't think of a better way immediately, however if you go with your wrapping in a struct/class option you could use a conversion operator to eliminate the member method or function call.
For example:
struct WrappedType
{
operator type()
{
return _value;
}
type _value;
}
I'm not saying this is the way to do it mind you ;-)
Upvotes: 7
Reputation: 573
There is a c++11 feature called enum class
, which is basically a type safe enum. Maybe they can help here.
Upvotes: 0