Since learning Rust, I've become a fan of the newtype idiom which I gather Rust borrowed from Haskell.
A newtype is a distinct type based on a standard type which ensures that function parameters are of the correct type.
For example, the old_enough
function below must be passed an age in Years. It will not compile with an age in Days or as a plain i64.
struct Days(i64);
struct Years(i64);
fn old_enough(age: &Years) -> bool {
age.0 >= 18
}
This is different from a typedef
or using
declaration in C++ which simply renames the type.
For example the old_enough
function below would accept an int
, an age in Days
, or anything else that converts to an int
:
typedef int Days;
using Years = int;
bool old_enough(Years age) {
return age >= 18;
}
As the example above just uses integers, this post on Reddit suggests using enum classes, e.g.:
enum class Days : int {};
enum class Years : int {};
bool old_enough(Years age) {
return static_cast<int>(age) >= 18;
}
Or it could simply use structures, like Rust e.g.:
struct Days final {int value;};
struct Years final {int value;};
bool old_enough(Years age) {
return age.value >= 18;
}
What is the best way to implement the newtype
idiom in C++
?
Is there a standard method?
EDIT the question Strongly typed using and typedef is similar. However, it does not consider the newtype
idiom.