Matt Eding
Matt Eding

Reputation: 1002

C++ Mixin using derived types

How can I pass along typedefs from a class to its mixin? At first I thought it may have been naming conflicts, but renaming value_t in the mixin doesn't help either.

template <typename Derived>
class Mixin
{
public:
    using value_t = typename Derived::value_t;
    
    Derived * self()
    {
        return static_cast<Derived *>(this);
    }
    
    value_t x() const
    {
        return self()->x;
    }
};

class DerivedInt : public Mixin<DerivedInt>
{
public:
    using value_t = int;
    value_t x = 0;
};

class DerivedDouble : public Mixin<DerivedDouble>
{
public:
    using value_t = double;
    value_t x = 0.0;
};

clang Semantic Issues:

file.h:14:39: error: no type named 'value_t' in 'DerivedInt'
file.h:27:27: note: in instantiation of template class 'Mixin<DerivedInt>' requested here

file.h:14:39: error: no type named 'value_t' in 'DerivedDouble'
file.h:34:30: note: in instantiation of template class 'Mixin<DerivedDouble>' requested here

Upvotes: 2

Views: 155

Answers (1)

Igor Tandetnik
Igor Tandetnik

Reputation: 52471

At the point where Mixin<DerivedInt> is instantiated, DerivedInt is an incomplete class - the compiler hasn't seen any of it beyond class DerivedInt. That's why DerivedInt::value_t is not recognized.

Perhaps something along these lines:

template <typename Derived, typename ValueType>
class Mixin
{
public:
    using value_t = ValueType;
};

class DerivedInt : public Mixin<DerivedInt, int> {
  // doesn't need its own `value_t` typedef.
};

Upvotes: 3

Related Questions