typeafe typedef в C ++ - PullRequest
       57

typeafe typedef в C ++

14 голосов
/ 06 марта 2012

Я бы хотел использовать что-то вроде typedef в моих программах на C ++ для повышения безопасности типов.

В качестве примера, предположим, что у меня есть две функции

void function1(unsigned idOfType1);
void function2(unsigned idOfType2);

, тогда я могу по ошибке передать idOfType2функционировать1 и наоборот.Я хочу, чтобы компилятор выдал мне ошибку в этом случае.Я знаю, что могу обернуть их без знака в структуру, но тогда мне нужно будет указать имя поля и использовать . для доступа к ним, что немного неудобно.Есть ли хороший способ обойти это?

Редактировать: Насколько я знаю typedef не будет работать для этой цели, поскольку это просто сокращение для типа и не будет использоваться для проверки типа.

Ответы [ 7 ]

16 голосов
/ 06 марта 2012

Use Boost strong typedef :

typedef создает псевдоним для существующего типа.Он не создает новый тип, который можно использовать для сопоставления параметров функции или шаблона ...

Использование BOOST_STRONG_TYPEDEF обращается к этому ...

BOOST_STRONG_TYPEDEF - это макрос, который генерируетКласс с именем "name" оборачивает и экземпляр своего примитивного типа и предоставляет соответствующие операторы преобразования для того, чтобы сделать новый тип заменяемым для того, который он переносит.

6 голосов
/ 06 марта 2012

Как вы говорите, typedef здесь вам не поможет. Я не могу сразу придумать лучшего способа, однако, если вы включите перенос в опцию struct / class, вы можете использовать оператор преобразования, чтобы исключить вызов метода или функции-члена.

Например:

struct WrappedType
{
    operator type()
    {
         return _value;
    }

    type _value;  
}

Я не говорю, что это способ сделать это, не забывайте; -)

2 голосов
/ 04 марта 2014

Я хочу это на языке.Не ответ как таковой, но ...:)

Непрозрачный typedefs

1 голос
/ 14 марта 2016

Это поздний ответ на старый вопрос. Но на фронте C ++ есть новые разработки, и для полноты картины я добавляю этот ответ:

Библиотека opaque_typedef - это попытка автора предоставить большую часть значений непрозрачных определений типов через библиотеку, не дожидаясь, пока непрозрачные определения типов станут языковой функцией.

Автор этой библиотеки, Кайл Маркли, произнес короткую блестящую речь на cppcon 2015 , представляющую эту библиотеку. Слайды его речи на github , исходный код библиотеки доступен на sourceforge . Библиотека только для заголовков, написана на C ++ 11. Gcc и clang в порядке, но VS2015, похоже, имеет проблемы с ним.

Использование библиотеки не вызывает затруднений. Следующий код был взят из документации. Это создает непрозрачный typedef из int. Он имеет тот же интерфейс, что и int (его можно добавлять, сдвигать, увеличивать, сравнивать и т. Д.), Но аргументы и возвращаемые значения относятся к вновь созданному типу, а не к int:

#include "opaque/numeric_typedef.hpp"

struct myint : opaque::numeric_typedef<int, myint> {
  using base = opaque::numeric_typedef<int, myint>;
  using base::base;
};
0 голосов
/ 05 декабря 2018

В сообщении в блоге foonathan за 2016 год рассматриваются различные подходы, начиная с примера класса для простых случаев:

class meter
{
public:
    explicit meter(int val)
    : value_(val) {}

    explicit operator int() const noexcept
    {
        return value_;
    }

private:
    int value_;
};

и заканчивая короткой библиотекой шаблонов с арифметической поддержкой пользовательскихтипобезопасные типы, позволяющие написать это:

struct meter
: strong_typedef<meter, int>, addition<meter>
{
    using strong_typedef::strong_typedef;
};
0 голосов
/ 06 марта 2012

Вы можете проверить тип в своей функции, чтобы, если он не совпадал, вы могли напечатать ошибку или что-то еще.

Вы можете использовать typeid для определения типа переменной следующим образом:

typeid(*variablename*).name()

Как предлагается в одном из ответов здесь , это зависит от компилятора, и вы должны использовать метод проб и ошибок, чтобы выяснить, какое значение вам подходит.

0 голосов
/ 06 марта 2012

Существует функция c ++ 11 под названием enum class, которая в основном является типом enum.Может быть, они могут помочь здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...