部分特化中不使用模板参数
我有以下代码:
template<typename T, typename Allocator = std::allocator<T> >
class Carray {
// ...
typedef T* pointer;
typedef pointer iterator;
// ...
};
现在我正在尝试对 iterator_traits
进行部分专业化。对我来说似乎没问题,但 g++ 4.4.5 抱怨:
#include <iterator>
namespace std {
template<typename T, typename Allocator>
struct iterator_traits<typename Carray<T, Allocator>::iterator> { // line 128
typedef T value_type;
typedef typename Allocator::difference_type difference_type;
typedef typename Allocator::reference reference;
typedef typename Allocator::pointer pointer;
typedef typename std::random_access_iterator_tag iterator_category;
};
}
这是完整的错误消息:
carray.h:128: error: template parameters not used in partial specialization:
carray.h:128: error: ‘T’
carray.h:130: error: ‘Allocator’ has not been declared
carray.h:131: error: ‘Allocator’ has not been declared
carray.h:132: error: ‘Allocator’ has not been declared
I have the following code:
template<typename T, typename Allocator = std::allocator<T> >
class Carray {
// ...
typedef T* pointer;
typedef pointer iterator;
// ...
};
Now I'm trying to do partial specialization for iterator_traits
. It seems OK to me, but g++ 4.4.5 complains:
#include <iterator>
namespace std {
template<typename T, typename Allocator>
struct iterator_traits<typename Carray<T, Allocator>::iterator> { // line 128
typedef T value_type;
typedef typename Allocator::difference_type difference_type;
typedef typename Allocator::reference reference;
typedef typename Allocator::pointer pointer;
typedef typename std::random_access_iterator_tag iterator_category;
};
}
This is the full error message:
carray.h:128: error: template parameters not used in partial specialization:
carray.h:128: error: ‘T’
carray.h:130: error: ‘Allocator’ has not been declared
carray.h:131: error: ‘Allocator’ has not been declared
carray.h:132: error: ‘Allocator’ has not been declared
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您根本不需要在这里进行专门化:
iterator_traits
已经专门用于指针类型,如果您最终得到的是类类型的迭代器,您只需定义那些所需的typedef
位于迭代器类中。问题是,为了匹配主要专业化,编译器需要获取使用模板的参数,将它们插入专业化,然后查看它们是否匹配。
考虑在以下简化场景中会发生什么:
编译器应该如何知道将什么
T
插入到S
中,或者是否某些S::type
的真正含义不仅仅是int
吗?问题在于嵌套的 typedef (
::type
) 取决于模板参数 (T
)。当函数参数列表或部分特化中出现这种情况时,无法推导类型T
(它是“非推导上下文”)。You shouldn't need a specialization at all here:
iterator_traits
is already specialized for pointer types and if you do end up with an iterator that is a class type, you can just define those requiredtypedef
s in the iterator class.The problem is that in order to match the primary specialization, the compiler needs to take the arguments with which the template is used, plug them into the specialization, and see whether they match.
Consider what would happen in the following simplified scenario:
How is the compiler supposed to know what
T
to plug intoS
or whether someS<T>::type
is really meant instead of justint
?The problem is that the nested typedef (
::type
) depends on the template parameter (T
). When this is the case in a function argument list or in a partial specialization, the typeT
cannot be deduced (it is a "non-deduced context").