I'd like the following piece of code to work:
template <typename Self>
struct foo_base {
auto get(typename Self::type n) { return n; }
};
template <typename T>
struct foo : public foo_base<foo<T>> {
using type = T;
};
The problem of course is that the base is instantiated first so you cannot refer to the derived member types. I'd need some kind of lazy-evaluation here.
I've tried to make the function template and have SFINAE on it, something like:
template <typename Self>
struct foo_base {
template <typename T, typename = std::enable_if_t<std::is_same_v<T, typename Self::type>>>
auto get(T n) { return n; }
};
but it doesn't seem to affect the order. Any ideas?
Edit:
Constraints of solution:
struct foo : foo_base<foo<T>, T>
or variants.You might create external traits, something like:
template <template T>
struct TypeT;
template <typename Self>
struct foo_base {
auto get(typename TypeT<Self>::type n) { return n; }
};
template <typename T> struct foo;
template <template T>
struct TypeT<foo<T>> {
using type = T; // Don't use foo<T>::type, so traits can be used with incomplete type
};
template <typename T>
struct foo : public foo_base<foo<T>> {
using type = typename TypeT<foo>::type; // Or directly = T
};
Else you might indeed use SFINAE, but you must wait the type to be complete (when instantiating the method works in your case), as for example:
template <typename Self>
struct foo_base
{
template <typename T = Self>
auto get(typename T::type n) { return n; }
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With