c++ type container that is code completion friendly?

Viewed 78

Consider the following code snippet:

#include <iostream>
#include <concepts>  

template<typename T>
concept Traits = requires(typename T::DispatcherT a, typename T::MsgT& b)
{
    { a.handleMsg(b) } -> std::same_as<void>;
};

struct MsgOne {
    int first{1};
};
struct MsgTwo {
    int first{10};
    double second{100.5};
};

struct DispatcherOne {
    void handleMsg(MsgOne& msg) { std::cout << "One: " << msg.first << '\n'; }
};
struct DispatcherTwo {
    void handle(MsgTwo msg) { std::cout << "Two: " << msg.first << " " << msg.second << '\n'; }
};

struct TraitsOne {
    using DispatcherT = DispatcherOne;
    using MsgT = MsgOne;
};

struct TraitsTwo {
    using DispatcherT = DispatcherTwo;
    using MsgT = MsgTwo;
};

template <Traits T> 
struct Driver {
    using DispatcherT = typename T::DispatcherT;
    using MsgT = typename T::MsgT;
    void handleMsg(MsgT &msg) { 
        dispatcher.handleMsg(msg); 
        //dispatcher. <- code completion fails to offer handleMsg(..)
    }
    DispatcherT dispatcher;
};

int main() {
    Driver<TraitsOne> driver{};
    MsgOne msg{};
    driver.handleMsg(msg);
}

the problem that i have here is that Clion IDE (v2022.2) (with clangd(v13) as LSP) does not offer code completion on an instance of DispatcherT inside of Driver<Traits T> template. Restricting the template parameter with a simpler concept such as

template<typename T>
concept Traits = requires(T a, MsgOne& b)
{
    { a.handleMsg(b) } -> std::same_as<void>;
};

works beautifully enter image description here but with the more complex Traits, code completion is lost. My question is: what would be an alternative way of defining a container of types that is code-completion friendly? I have thought about std::tuple<> but haven't tried it since accessing the types might be a bit cumbersome (imho). It seems Visual Studio is offering intellisense but I am constrained to use clangd. Any ideas and critisisms are welcome!

0 Answers
Related