В С ++ 20:
using A = decltype([]{}); // an idiom
using B = decltype([]{});
...
Это идиоматический код: так пишется «дай мне уникальный тип» в C ++ 20.
В C ++ 11 самый ясный и простой подход использует __LINE__
:
namespace {
template <int> class new_type {};
}
using A = new_type<__LINE__>; // an idiom - pretty much
using B = new_type<__LINE__>;
Анонимное пространство имен является наиболее важным битом. Серьезная ошибка - не помещать класс new_type
в анонимное пространство имен: типы тогда не будут более уникальными для единиц перевода. Все виды веселья начнутся за 15 минут до того, как вы планируете отправить:)
Это распространяется на C ++ 98:
namespace {
template <int> class new_type {};
}
typedef new_type<__LINE__> A; // an idiom - pretty much
typedef new_type<__LINE__> B;
Другой подход заключается в том, чтобы вручную связать типы в цепочку, и чтобы статический компилятор проверял, правильно ли было выполнено связывание, и выдавал ошибку, если вы этого не делаете. Так что это не будет хрупким (при условии, что магия сработает).
Что-то вроде:
namespace {
struct base_{
using discr = std::integral_type<int, 0>;
};
template <class Prev> class new_type {
[magic here]
using discr = std::integral_type<int, Prev::discr+1>;
};
}
using A = new_type<base_>;
using A2 = new_type<base_>;
using B = new_type<A>;
using C = new_type<B>;
using C2 = new_type<B>;
Требуется лишь немного волшебства, чтобы строки с типами A2 и C2 не компилировались. Возможна ли эта магия в C ++ 11 - другая история.