Typafe typedef в С++

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

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

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

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

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

Ответы

Ответ 1

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

Например:

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

    type _value;  
}

Я не говорю, что это способ сделать это с уважением; -)

Ответ 2

Используйте Повысьте уровень typedef:

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

Использование BOOST_STRONG_TYPEDEF адресов...

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

Ответ 4

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

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

Автор этой библиотеки, Кайл Маркли, короткая блестящая речь на cppcon 2015, представляющая эту библиотеку. Слайды его речи находятся на github исходный код библиотеки доступен на sourceforge. Библиотека имеет только заголовок, написанный на С++ 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;
};

Ответ 5

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

Ответ 6

В блоге блога 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;
};

Ответ 7

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

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

typeid(*variablename*).name()

Как было предложено в одном из ответов здесь, это зависит от компилятора, и вам нужно использовать метод try-and-error, чтобы узнать, какое значение работает для вас.