Home > database >  How to tell if template type is an instance of a non-variadic template class?
How to tell if template type is an instance of a non-variadic template class?

Time:10-16

This question is awful similar to How to tell if template type is an instance of a template class?

I would like to detect if a template parameter is from one particular template class that has no variadic template arguments.

template<class U, class S>
struct A{};

template<class T>
struct B {
  B() {
    if constexpr (T == A) {
      // T is a template instantiation of `A`.
    } else {
    }
  }
};

I can't change A's definition. I can change B's definition to have additional template parameters.

How do I implement (T == A) given the restriction of not knowing A's U and S?

CodePudding user response:

I would go for a partial specialization here.

#include <iostream>

template<class U, class S>
struct A{};

template<class T>
struct B {
    B() {
        std::cout << "None-A implementation\n";
    }
};

template<class U, class S>
struct B<A<U, S>> {
    B() {
        std::cout << "A implementation\n";
    }
};

int main() {
    B<int> b1;
    B<A<int, int>> b2;
}

You have the option of leaving the default-case without an implementation.

Or you can have a fallback implementation for any none-A classes like here.

If the partial specialization forces too much code duplication you can also extract the detection part to it's own template variable like this.

#include <iostream>

template<class U, class S>
struct A{};

template <class T>
constexpr bool is_A_instatiation = false;

template <class U, class S>
constexpr bool is_A_instatiation<A<U, S>> = true;

template<class T>
struct B {
    B() {
        if constexpr (is_A_instatiation<T>) {
            std::cout << "A instatiation!\n";
        } else {
            std::cout << "none-A instatiation!\n";
        }
    }
};

int main() {
    B<int> b1;
    B<A<int, int>> b2;
}

CodePudding user response:

The easiest way is:

template<class T>
struct B{/*default implementation*/};

template<class U,class S>
struct B<A<U,S>>{/*Specified implementation*/};

CodePudding user response:

If I didn't misunderstand;

  • A<T,U>: you already know it and search key
  • B<...>: variadic types which may include A<T,U> - known type

And you want to search A<T,U> in B<...>


template <typename T, typename U>
struct A {};

template <typename T, typename U, typename ...Ts>
struct B {
    static constexpr bool value = ((std::is_same_v< A<T, U>, Ts> || ... ));
};

int main() {
    std::cout << std::boolalpha << 
    B<int,float, int, int, float, A<int,float>>::value << '\n'<<
    B<int,float, int, int, float>::value <<std::endl;
}

  • Related