Is there any way of detecting whether a class is a normal type or is an instantiation of a template type (meta type) which may include non-type parameters? I came up with this solution:
#include <iostream>
template <template<class...> class>
constexpr bool is_template()
{
return true;
}
template <class>
constexpr bool is_template()
{
return false;
}
struct Foo{};
template<class> struct TemplateFoo{};
template<class, int> struct MixedFoo{};
int main()
{
std::cout << std::boolalpha;
std::cout << is_template<Foo>() << std::endl;
std::cout << is_template<TemplateFoo>() << std::endl;
// std::cout << is_template<MixedFoo>() << std::endl; // fails here
}
however it will fail for templates that mix non-types and types, like
template<class, int> struct MixedFoo{};
I am not able to come up with any solution, except the one in which I must explicitly specify the types in the overloads. Of course this is un-reasonable due to combinatorial explosion.
Related question (not a dupe): Is it possible to check for existence of member templates just by an identifier?
In Visual Studio 2017 and later, and in /std:c++17 mode or later, the compiler deduces the type of a non-type template argument that's declared with auto: A template can be a template parameter. In this example, MyClass2 has two template parameters: a typename parameter T and a template parameter Arr:
Line 1 declares a class template that has two template parameters. Okay, the first parameter is the type of the elements and the second parameter stands for the container. Let's have a closer look at the second parameter: template <typename, typename> class Cont >.
The primary restriction when using templates is that a type argument must support any operations that are applied to the type parameters. For example, if we call minimum using MyClass as in this example:
Only class templates may be partially specialized. All complete and partial specializations of a template must be declared in the same namespace as the original template. For more information, see Template Specialization.
No, there is not.
Note that template classes are not classes themselves. They are templates for classes.
I guess it is not possible.
Anyway, you can use the other way around and let N
be deduced:
template<class, class> struct MixedFoo;
template<class C, int N> struct MixedFoo<C, std::integral_constant<int, N>>{};
Now, this returns true
as expected:
std::cout << is_template<MixedFoo>() << std::endl; // fails here
Of course, you won't be able anymore to use MixedFoo
as MixedFoo<int, 2>
, so I'm not sure it's worth it.
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