Создание новых типов в C ++ - PullRequest
20 голосов
/ 22 августа 2011

Использование typedef в C ++ создает псевдоним для типа.

Итак:

typedef double Length;
typedef double Mass;

создает два псевдонима, которые могут быть смешаны. Другими словами, мы можем передать значение типа Mass функции, которая ожидает значение типа Length.

Есть ли легкий способ создания новых типов? Я хотел бы, чтобы они были двойными снизу, но были «другими», чтобы одно не могло быть использовано вместо другого.

Я бы предпочел что-то более легкое, чем создание нового класса или структуры. Также мне известны размеры lib в boost. Это сложнее и делает гораздо больше, чем мне нужно.

Ответы [ 4 ]

19 голосов
/ 22 августа 2011

BOOST_STRONG_TYPEDEF, кажется, предназначен именно для того, что вы ищете. Я считаю, что это делает чудо, создавая класс и перегружая операторы, чтобы он вел себя как встроенный тип, но я не смотрел на его реализацию.

11 голосов
/ 22 августа 2011

Хотя BOOST_STRONG_TYPEDEF - довольно простое решение, если вы смешиваете длины и массы в более сложные единицы (например, в физических науках), то вы можете использовать Boost.Units .

1 голос
/ 25 сентября 2018

Еще один возможный ответ в C ++ 11 - использовать enum class: type.Это позволит вам делать то, что вы хотите, но у него есть свои недостатки.Например, вам придется перегружать множество операторов.

#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);
}

Это даст результат:

A 42
B 0

Или вы можете просто получить целую часть, подобную этой

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

std::cout << "B " << GetInt(t) << std::endl;
1 голос
/ 29 июня 2017

Если предложение Metaclasses (p7070) будет выполнено (сейчас оно все еще на revision0 ), тогда мы сможем создать сильные определения типов, используя пустой метаклассПредложенный синтаксис:

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

Как можно раньше мы увидим, что это будет C ++ 20

...