Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way of detecting arbitrary template classes that mix types and non-types?

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?

like image 957
vsoftco Avatar asked Oct 02 '16 00:10

vsoftco


People also ask

How does the compiler determine the type of a non-type template argument?

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:

What are the two template parameters in a class template?

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 >.

What are the restrictions when using templates in Java?

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:

Can a class template be partially specialized?

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.


2 Answers

No, there is not.

Note that template classes are not classes themselves. They are templates for classes.

like image 188
Yakk - Adam Nevraumont Avatar answered Nov 06 '22 15:11

Yakk - Adam Nevraumont


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.

like image 36
skypjack Avatar answered Nov 06 '22 16:11

skypjack