Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
322 views
in Technique[技术] by (71.8m points)

c++ - Is it possible to check if a type has been instantiated with a specific template parameter?

Not quite sure if my terminology is 100% correct, so here's the code:

template<class... Ts>
struct Empty { };

int main() {
   using T = Empty<int, double>;
   // How to check if T "contains" double?

   return 0;
}

So this is specifically for types that accept multiple template types. Also this would ideally be at compile time. Bonus points if it doesn't need an object of the type.

The closest I was able to get (with help) was this:

template <class check, class T, class... U>
constexpr bool contains_type(){
   if constexpr (std::is_same_v<T, check>)
      return true;
   else if constexpr (sizeof...(U) > 0)
      return contains_type<check, U...>();
   else
      return false;
}


template <class check, template<class> class TypeToCheck, class... T>
constexpr bool does_obj_contain_type(TypeToCheck<T...>) {
   if constexpr (sizeof...(T) > 0)
      return contains_type<check, T...>();
   else
      return false;
}

constexpr bool does_contain_double = does_obj_contain_type<double>(T{});

That contains C++ syntax I've never before seen, but it works. Would be neat if it wouldn't require the T{} object. And maybe look a bit saner.

question from:https://stackoverflow.com/questions/65891004/is-it-possible-to-check-if-a-type-has-been-instantiated-with-a-specific-template

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Not sure to understand what do you exactly want... but I suppose is something as

template <class check, template<class...> class TypeToCheck, class... T>
constexpr bool does_obj_contain_type(TypeToCheck<T...>) {
   return (std::is_same_v<check, T> || ...);
}

// ...

using T = Empty<int, double>;

auto x = does_obj_contain_type<double>(T{});

But it's a problem if you can't instantiate an object of type T. In the case, I suppose you can use class/struct specialization.

Something as

template <typename>
struct does_obj_contain_type;

template <template <typename...> class TTC, typename ... Ts>
struct does_obj_contain_type<TTC<Ts...>>
 {
   template <typename check>
   static constexpr bool func ()
    { return (std::is_same_v<check, Ts> || ...); }
 };

 // ...

 using T = Empty<int, double>;

 constexpr auto x = does_obj_contain_type<T>::func<double>();

Or maybe better as a template variable value (suggested by super: thanks!)

template <template <typename...> class TTC, typename ... Ts>
struct does_obj_contain_type<TTC<Ts...>>
 {
   template <typename Check>
   static constexpr auto value = (std::is_same_v<Check, Ts> || ...);
 };

// ...

using T = Empty<int, double>;

constexpr auto x = does_obj_contain_type<T>::value<double>;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...