Collect instantiated template types at compile time

202 Views Asked by At

Consider this snippet:

struct A {

  template <typename T> void bar(const T &) {
    /*
    I would like to write something like:
        if constexpr(type T already processed/T is already present in typelist)
        ...do something fancy
        else if constexpr(type T not processed/T is not present in typelist)
    */
  }
};

struct Msg1 {};
struct Msg2 {};

int main() {
  A a;

  a.bar(Msg1{});
  a.bar(Msg1{});
}

Demo

Is it possible to see at compile time for which types the method bar was already instantiated?

Ideally, there would be some kind of growing typelist, where one can check at compile time for which types bar is already instantiated.

1

There are 1 best solutions below

1
On

No. It is not possible to do so at compile time. However, it would be possible to do the following at runtime:

#include <typeindex>
#include <type_traits>
#include <unordered_set>
struct A {
    private:
    std::unordered_set<std::type_index> already_processed_ts;
    public:
    template<typename T>
    void bar(const T&){
        if(already_processed_ts.find(typeid(T)) != already_processed_ts.end())
            std::cout << "Already processed " << typeid(T).name() << std::endl;
        else{
            already_processed_ts.insert(typeid(T));
            std::cout << "Processing " << typeid(T).name() << "... \n";
        }
    }
}
struct Msg{};
int main()
{
    f(Msg{}); // Prints "Processing 3Msg..." (at least on my compiler)
    f(Msg{}); // Prints "Already processed 3Msg"

    return 0;
}