Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using inner class with CRTP

Tags:

c++

crtp

Is there any possibility to use inner class or enum with CRTP? Ex.

template<typename Container>
struct ContainerBase
{
    std::map<typename Container::Enum, int> _;
};
struct ConcreteContainer : ContainerBase<ConcreteContainer>
{
    enum class Enum
    {
        left,
        right
    };
};
like image 404
MamCieNaHita Avatar asked Aug 24 '17 10:08

MamCieNaHita


1 Answers

No. Within the class template the derived class isn't fully defined yet (that's not a complete object in standardese).
In fact (working draft):

A class is considered a completely-defined object type (or complete type) at the closing }

Therefore you cannot expect to be able to access one of the members or whatever you declared in the derived class from within the class template.

You can work around it by passing the enum separately, but it requires you to define the enum somewhere else (Another base class? The outer scope? Whatever...). You can work around by using traits classes. And so on.
There are several alternatives to do that, but you cannot access directly the enum defined in the derived class.
Here is an example of a viable solution:

#include <map>

template<typename> struct traits;

template<typename Container>
struct ContainerBase
{
    std::map<typename traits<Container>::Enum, int> _;
};

template<>
struct traits<struct ConcreteContainer> {
    enum class Enum
    {
        left,
        right
    };
};

struct ConcreteContainer : ContainerBase<ConcreteContainer>
{};

int main() {
    ConcreteContainer cc;
    cc._[traits<ConcreteContainer>::Enum::left] = 0;
    cc._[traits<ConcreteContainer>::Enum::right] = 1;
}

See it up and running on wandbox.

like image 146
skypjack Avatar answered Nov 15 '22 04:11

skypjack