user905122
user905122

Reputation: 325

Creating new types in C++

Using typedef in C++ creates an alias for a type.

So:

typedef double Length;
typedef double Mass;

creates two aliases which can be intermixed. In other words we can pass a value of type Mass to a function that expects a value of type Length.

Is there a lightweight way of creating new types? I would like them to be double underneath but be "different" so that one can't be used in place of another.

I would prefer something lighter than creating a new class or struct. Also, I am aware of the dimensions lib in boost. This is more complex and does a lot more than I need.

Upvotes: 30

Views: 18039

Answers (4)

Strahinja Radman
Strahinja Radman

Reputation: 124

One other possible answer in C++11 is to use enum class : type. This will allow you to do what you want but it has its own downsides. For example you would have to overload a lot of operators.

#include <iostream>
#include <string>

enum class A : int; 
enum class B : int;

std::ostream& operator<<(std::ostream& os, const A& t){
    os << static_cast<int>(t);
    return os;
}

std::ostream& operator<<(std::ostream& os, const B& t){
    os << static_cast<int>(t);
    return os;
}

int test(A t){
    std::cout << "A " << t << std::endl;
    return 0;
}

int test(B t){
    std::cout << "B " << t << std::endl;
    return 0;
}

int main(){
    A a{static_cast<A>(42)};
    B b{static_cast<B>(0)};

    test(a);
    test(b);
}

This would give the output of:

A 42
B 0

Or you could just get the integer part like this

template<class T>
int GetInt(T t)
{
    return static_cast<int>(t);    
}

std::cout << "B " << GetInt(t) << std::endl;

Upvotes: 4

AndyG
AndyG

Reputation: 41090

If the Metaclasses proposal (p7070) goes through (right now it's still at revision0), then we shall be able to create strong typedefs using an empty metaclass. Proposed syntax:

$class strong_typedef { };
using Length = $double.as(strong_typedef);
using Mass = $double.as(strong_typedef);

Earliest we might see this would be C++20

Upvotes: 2

Ken Bloom
Ken Bloom

Reputation: 58770

While BOOST_STRONG_TYPEDEF is a pretty simple solution, if you're mixing lengths and masses into more complicated units (e.g. in the physical sciences) then you might want to use Boost.Units.

Upvotes: 11

Billy ONeal
Billy ONeal

Reputation: 106530

BOOST_STRONG_TYPEDEF seems to be designed exactly for what you're looking for. I believe it does it's magic by creating a class and overloading the operators to make it behave like a builtin type, but I've not looked at it's implementation.

Upvotes: 24

Related Questions