I know that this is basically a workaround that you found that you don't like, but I wanted to document it, and also say that this is basically the current solution to this problem.
I have been looking for a way to do this for a long time and have not found a good solution. The fact that this is not possible is the reason that in the end, things like boost::iterator_facade<Self, different_type, value_type,...> require a lot of parameters.
Of course, we would like something like this to work:
template<class CRTP> struct incrementable{ void operator++(){static_cast<CRTP&>(*this).increment();} using ptr_type = typename CRTP::value_type*;
If it were possible, all the features of the derived class could be passed implicitly from the base class. The idiom I found to get the same effect is to pass the traits to a fully base class.
template<class CRTP, class ValueType> struct incrementable{ void operator++(){static_cast<CRTP&>(*this).increment();} using value_type = ValueType; using ptr_type = value_type*; }; template<class T> struct A : incrementable<A<T>, T>{ void increment(){} typename A::value_type f() const{return typename A::value_type{};}
https://godbolt.org/z/2G4w7d
The disadvantage is that the attribute in the derived class must be accessed with qualified typename or reused using with using .
alfC Jan 16 '19 at 7:04 2019-01-16 07:04
source share