I know there are a lot of posts about "Explicit specialization in non-namespace scope"; I already read most of them but (unless I didn't understand the answers well) they don't answer this specific question. As a matter of fact, I found a workaround in my program, but I'm interested to know the "real solution" to this problem if there is one.
Please bear with me, it's difficult to put into words. I have a template class A<typename T, unsigned n>
. I want to define a type-checker as a template inner struct is_A<typename U>
which checks if U
is some A
. This struct inherits from std::false_type
as is, and I specialize it to derive from std::true_type
for template types A<U,n>
.
Why do I want to do this? Because I want to define a template method A::method<U>
that behaves differently when U
is some A
or otherwise.
is_a<U>
before the declaration of A
. And put the specialized version afterwards with 2 template arguments instead of 1; ie template <> template <typename T, unsigned n> struct is_A< A<T,n> > : std::true_type {};
. Why not, but I don't like so much adding a template argument, and exploding the definition of is_A
is not so pretty either...is_A
and using another type-checker for method
which caracterizes precisely the type I expect (ie, whitelist approach instead of blacklist).Is there another way than these workarounds which allows to write something similar to the following header?
Here is the smallest header I could write to reproduce the error:
#ifndef __EXAMPLE__
#define __EXAMPLE__
#include <type_traits>
namespace name
{
template <typename T, unsigned n>
class A
{
public:
/**
* Type checkers
*/
template <typename U>
struct is_A : public std::false_type {};
template <> template <typename U>
struct is_A< A<U,n> > : public std::true_type {};
/**
* Specialized method
*/
// Version taking input of type A<U,n>
template <typename U>
void method( const A<U,n>& other ) {}
// Version taking inputs of other types
template <typename U,
typename = typename std::enable_if< !is_A<U>::value >::type >
void method( const U& x ) {}
};
}
#endif
Here is the error I get when I compile a cpp file including this header:
.h:21:12: error: explicit specialization in non-namespace scope 'class name::A<T, n>'
.h:30:7: error: too many template-parameter-lists
.h:35:7: error: too many template-parameter-lists
It seems to work for me if you do as the compiler advises: Leave out the template<>
:
template <typename U>
struct is_A< A<U,n> > : public std::true_type {};