Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a type is instantiation of a template

Tags:

I want to check if a type is instantiation of a particular template during compilation.

For example:

  1. std::vector<int> is instantiation of std::vector
  2. std::array<int, 5> is instantiation of std::array

I can make a test that works for case 1 but does not work for case 2.

#include <iostream> #include <type_traits> #include <string> #include <vector> #include <array> #include <queue> template<template<typename...> class, typename...> struct is_instantiation : public std::false_type {};  template<template<typename...> class U, typename... T> struct is_instantiation<U, U<T...>> : public std::true_type {};  int main() {     using A = std::vector<int>;     std::cout << is_instantiation<std::vector, A>::value << "\n";     std::cout << is_instantiation<std::queue, A>::value << "\n";     // std::cout << is_instantiation<std::array, A>::value << "\n"; } 

How to make it work for both cases?

I tried auto, but can't make it work.

Advantages of auto in template parameters in C++17

like image 395
R zu Avatar asked May 11 '18 03:05

R zu


People also ask

What is the instantiation of the class template?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation.

How do I force a template instantiation?

To instantiate a template function explicitly, follow the template keyword by a declaration (not definition) for the function, with the function identifier followed by the template arguments. template float twice<float>(float original); Template arguments may be omitted when the compiler can infer them.

How the instantiation of function template happens?

When a function template is first called for each type, the compiler creates an instantiation. Each instantiation is a version of the templated function specialized for the type. This instantiation will be called every time the function is used for the type.

Which of the data types are supported by template?

All data types, both primitive and compound types, must be defined by using a template.


1 Answers

Spezialized std::array size

The only way I see is to make specialized Array classes with pre-defined array sizes. Something like this:

#include <iostream> #include <type_traits> #include <string> #include <vector> #include <array> #include <queue> template<template<typename...> class, typename...> struct is_instantiation : public std::false_type {};  template<template<typename...> class U, typename... T> struct is_instantiation<U, U<T...>> : public std::true_type {};  template <class T> class My5Array {     public:     My5Array() { }     private:     std::array<T, 5> arr; };  template <class T> class My10Array {     public:     My10Array() { }     private:     std::array<T, 10> arr; };  int main() {     using A = std::vector<int>;     using B = My5Array<int>;     std::cout << is_instantiation<std::vector, A>::value << "\n";     std::cout << is_instantiation<std::queue, A>::value << "\n";     std::cout << is_instantiation<My5Array, A>::value << "\n";     std::cout << is_instantiation<My5Array, B>::value << "\n";     std::cout << is_instantiation<My10Array, B>::value << "\n"; } 

prints

1 0 0 1 0 

Of course, there are disadvantages:

  • possibly waste of memory due to fixed array size
  • multiple classes needed for desired array sizes
  • usage of non-standard type MyXArray
  • obviously an instance of My5Array cannot be an instance of My10Array at the same time (see var B in code above)

1st possible alternative: std::dynarray

I have also found std::dynarray, which could work instead of std::array, but I think that it is not yet included in the latest C++ standards. Maybe worth keeping an eye on it.

2nd possible alternative: just let it drop

The standard container available are possibly sufficient for most applications.

like image 157
tangoal Avatar answered Oct 12 '22 18:10

tangoal