Home > database >  Concept of template class in C 20
Concept of template class in C 20

Time:10-09

I'm new in advanced usage of templates and concepts, so here is a liitle bit complex problem:

  • I have some Traits concept of many traits for each of Source classes:

    template<typename _Traits>
    concept Traits = requires
    {
       std::same_as<std::decay_t<decltype(_Traits::token)>, std::string_view>;
    };
    
  • I have some template class that uses this concept to handle object_one with various traits (for example, half of Source classes returns object_one):

    template <concepts::Traits _Traits>
    class Object_one_handler final
    {
        static std::string handle_object(const object_one& obj) {/*...*/}
    };
    
  • Then I have Objects_handlers concept of handlers for various objects from set {object_one, object_two, object_three} from various Sources with their Traits:

    template<template <concepts::Traits _Traits> class _Objects_handlers, typename _Object>
    concept Objects_handlers = requires(const _Object& obj)
    {
       // has handle_object method
       { _Objects_handlers<???????>::handle_object(obj) } -> std::same_as<std::string>;
    };
    
  • Finally, I creating some database with specified as template parameter Object_handler:

    template<concepts::Objects_handlers _handler>
    class database 
    {...};
    

(Actually all of concepts have additional requirements, but it doesn't matter here)


So problem is in last Objects_handlers concept:

template<template <concepts::Traits _Traits> class _Objects_handlers, typename _Object>
concept Objects_handlers = requires(const _Object& obj)
{
  // has handle_object method
  { _Objects_handlers<???????>::handle_object(obj) } -> std::same_as<std::string>;
                      ^^^^^^^
};

I can't check _Objects_handlers method without template parameter (obviously) and I can't properly set the template parameter which must be one of Traits.

How can I do that?

And actually it may be problem in usage of Objects_handlers in template of database class, so one more question: how to use it?


P.S. It can be XY problem or not about concepts at all... Maybe composition with strategy pattern will be more usefull, but still want try to create this maybe useless, but workable concept.

CodePudding user response:

Let's reduce this problem a lot.

template <typename T>
struct C {
    void f();
};

Now, your goal is to write a concept that takes any class template (e.g. C) and checks that every specialization of it has a nullary member function named f.

template <template <typename> class Z>
concept HasF = requires (Z<???> z) {
    z.f();
};

The problem is - class templates in C just don't work like this. Even for a particular class template, like C, you can't require that every specialization has f. There's no way to ensure that like somebody, somewhere, didn't add:

template <> struct C<std::vector<std::list<std::deque<int>>>> { };

All you can do is check that a specific type has a nullary member function named f. And that's:

template <typename T>
concept HasF = requires (T t) { t.f(); };

The type-constraint syntax, template <Concept T>, is only available for concepts that constrain types, not concepts that constrain templates or values.

  • Related