Здравствуйте, niralex, Вы писали:
R>>Можно вынести идентификацию типов за пределы классов. Это позволит присвоить идентификаторы не только пользовательским типам, но и встроенным. После чего идентификаторы можно будет пробовать как-то комбинировать:
R>>R>>template <typename> struct TypeID;
R>>template<> struct TypeID<int> : std::integral_constant<int, 1> { };
R>>template<> struct TypeID<std::string> : std::integral_constant<int, 2> { };
R>>template<> struct TypeID<MyType1> : std::integral_constant<int, 3> { };
R>>template<> struct TypeID<MyType2> : std::integral_constant<int, 4> { };
R>>template <typename T>
R>>struct TypeID<MyType3<T>> : std::integral_constant<int, 420000 + TypeID<T>::value> {};
R>>
R>>P.S. Синтаксический сахар и диагностику можно добавить во вкусу.
N>Да, это было бы прекрасным решением, но дело в том что есть такие пользовательские типы как template<typename ...T> MyTuple {} и там "как-то комбинировать" не получается, слишком много комбинаций шаблонных типов. Я пришел к выводу, что для идентификатора нужен все-таки массив, но тогда не получается сделать идентификацию constexpr.
N>А идея с вынесением за пределы классов хорошая, спасибо.
Начиная с C++17 есть
fold expressions. Вот они как раз позволят и охватить множество комбинаций, и сохранить constexpr:
template <typename...T>
struct TypeID<MyType3<T...>> : std::integral_constant<int, 420000 + ... + TypeID<T>::value> {};
Ну, понятно, что способ комбинирования нужно додумывать так, чтобы он исключал коллизии и обеспечивал уникальные айдишники.