Home > Software engineering >  Nested concept types in templates
Nested concept types in templates

Time:06-30

Consider the following template, intended on declaring some State::Machine:

enum Strategy {
   Breadth,
   Depth,
   Heuristic,
};

template<class Map, Strategy Strategy = Depth>
struct Machine;

If we would like to enforce some constraints on the Map type, so that implementations satisfy necessary concepts, we have:

template <Range::Type Source, Comparable Constraint, class Result, Transition<Source, Constraint, Result> Transition, Range::Of<Transition> Transitions, Map<Constraint, Transitions> Map, Strategy Strategy = Strategy::Depth>
class Machine {

};

Where Source is some container like std::vector, Constraint is some comparable struct == struct -> bool, Transition is some lambda(Source) -> Product and Transitions is some container of Transition.

Declaring this type is now exhausting:

auto transition = [](std::string source) {
    return State::Product<std::string, State, State> {
            .source = source,
            .state = State::Start,
            .product = State::Start,
    };
};
static_assert(Transition<decltype(transition), std::string, State, State>);

std::map<State, std::set<decltype(transition)>> map = {
        {State::Start, {transition}}
};

State::Machine<std::string, State, State, decltype(transition), std::set<decltype(transition)>, decltype(map)> machine;

Is there a way to have all the concepts be required with only one type parameter

State::Machine<decltype(map)> machine;

Similar to how it was before any concepts were required?

CodePudding user response:

Most types expose their "subtypes". std::map has key_type and mapped_type for example.

(You can create traits to extract template parameter if needed BTW, if type doesn't provide such typedef).

Then you might use constraint on those sub-types, something like:

template <typename Map, Strategy Strategy = Strategy::Depth>
requires(Comparable<typename Map::key_type>
     && IsATransition<typename Map::mapped_type>)
class Machine
{
    // ...
};
  • Related