Я ищу способ автоматически сделать параметр шаблона по умолчанию уникальным каждый раз, когда создается экземпляр шаблона. Поскольку объекты безымянных функций, создаваемые лямбда-выражениями, имеют разные типы, я подумал о том, чтобы как-то их принять. В связи с недавними изменениями в стандартном отчуждении, снятие ограничения "лямбда-выражение не должно появляться в... аргументе шаблона" (см. Формулировку лямбда-выражения в неоцененном контексте) показалось хорошей идеей. Итак, я написал следующий своего рода рабочий фрагмент, который компилируется на последних gcc и clang:
#include <type_traits>
template<void ( * ) (void) = [](){}> class
unique final {};
static_assert(false == ::std::is_same_v<unique<>, unique<>>);
int main()
{
return 0;
}
Это жизнеспособный подход или один из тех "плохо сформированных, не требующих диагностики" случаев?
Некоторый дополнительный контекст: я хочу использовать это для реализации определений строгого типа в стиле Ады, которые должны работать в одном модуле перевода без ручного изобретения уникальных тегов, которые в противном случае были бы неиспользованными:
struct _tag_WowInt {};
using Int = type<int, _tag_WowInt>;
struct _tag_SoUnique {};
using DifferentInt = type<int, _tag_SoUnique>;
Upd1: Я хотел бы отметить, что подходы, включающие __COUNTER__
или подобные макросы, не будут работать в общем случае, потому что они будут расширены препроцессором только один раз и не будут давать уникальные типы при использовании, например, внутри шаблона.