I would like to have a nice way to enable functionality(e.g. ++, *=, /) of my strong types(e.g. StockPrice, Count).
I don't like using inheritance for that (CRTP/mixins), I understand some may like it but I prefer to not use inheritance for this use case.
So I have code like this:
template<class, template<class...> class>
inline constexpr bool is_specialization = false;
template<template<class...> class T, class... Args>
inline constexpr bool is_specialization<T<Args...>, T> = true;
template<typename Underlying, typename TagType>
struct StrongT{
Underlying val;
using Tag = TagType;
};
template<typename T>
concept addable = is_specialization<T, StrongT> && requires (T& t){
typename T::Tag::addable_trait;
};
struct IndexTag{
using addable_trait = int;
};
using Index = StrongT<size_t, IndexTag>;
struct NanosTag{
using addable_trait = int;
};
using Nanos = StrongT<size_t, struct NanosTag>;
template<addable T>
T operator + (const T& a, const T& b){
return T{a.val+b.val};
}
I like it since I can list my "traits" in tag struct, but I dislike it since it is a bit spammy. I can not declare tag struct inline like this:
using Nanos = StrongT<size_t, struct NanosTag{/*...*/}>;
So is there way to do what I want in a shorter way, without using inheritance?
note: I only have one trait/concept here, obviously I want many traits supported, e.g. comparable/incrementable...