我知道有很多关于“非命名空间范围内的显式专业化”的帖子;我已经阅读了大部分内容但是(除非我不能很好地理解答案)他们没有回答这个具体问题。事实上,我在我的程序中找到了一个解决方法,但是我有兴趣知道这个问题的“真正解决方案”。如果有的话。
请忍受我,很难说出来。我有一个模板类A<typename T, unsigned n>
。我想将一个类型检查器定义为模板内部结构is_A<typename U>
,它检查U
是否为某个A
。此结构继承自std::false_type
,并且我专门从std::true_type
派生模板类型A<U,n>
。
为什么我要这样做?因为我想定义一个模板方法A::method<U>
,当U
为某个A
时,其行为会有所不同。
is_a<U>
声明之前加上A
的非专业定义。然后把专门版本放在2个模板参数而不是1; 即 template <> template <typename T, unsigned n> struct is_A< A<T,n> > : std::true_type {};
。为什么不呢,但我不太喜欢添加模板参数,而且is_A
的定义爆炸也不是那么漂亮...... is_A
并使用另一种method
类型检查器,它可以准确描述我期望的类型(即,白名单方法而不是黑名单)。除了这些解决方法之外还有其他方法可以编写类似于以下标题的内容吗?
这是我为重现错误而编写的最小标题:
#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
以下是编译包含此标题的cpp文件时出现的错误:
.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
答案 0 :(得分:3)
如果按照编译器的建议,它似乎对我有用:省略template<>
:
template <typename U>
struct is_A< A<U,n> > : public std::true_type {};