I want to check if a type is instantiation of a particular template during compilation.
For example:
std::vector<int>
is instantiation of std::vector
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
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.
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.
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.
All data types, both primitive and compound types, must be defined by using a template.
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:
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.
The standard container available are possibly sufficient for most applications.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With