I'm looking for a way to automatically make default template parameter be unique each time a template is instantiated. Since unnamed function objects created by lambda expressions have different types I thought of adopting them somehow. With recent changes to standard daft removing "A lambda-expression shall not appear in ... a template-argument" restriction (see Wording for lambdas in unevaluated contexts) it seemed like a good idea. So I wrote the following kinda working snippet that compiles on recent gcc and clang:
#include <type_traits>
template<void ( * ) (void) = [](){}> class
unique final {};
static_assert(false == ::std::is_same_v<unique<>, unique<>>);
int main()
{
return 0;
}
Is this a viable approach or one of those "ill-formed, no diagnostic is required" cases?
Some additional context: I want to use this to implement Ada-style strong type definitions that should work in a single translation unit without manually inventing unique tags that would be otherwise unused:
struct _tag_WowInt {};
using Int = type<int, _tag_WowInt>;
struct _tag_SoUnique {};
using DifferentInt = type<int, _tag_SoUnique>;
Upd1: I would like to mention that approaches involving __COUNTER__
or similar macros won't work in general case because they will be expanded by preprocessor only once and won't yield unique types when used inside of template for example.