4

我有以下代码:

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
4

1 回答 1

10

您在这里根本不需要专门化: iterator_traits已经专门用于指针类型,如果您最终得到了一个类类型的迭代器,您只需typedef在迭代器类中定义那些 required s。

问题在于,为了匹配主要特化,编译器需要获取使用模板的参数,将它们插入特化,并查看它们是否匹配。

考虑在以下简化场景中会发生什么:

template <typename T> struct S { typedef int type; };

template <typename T> 
struct Traits { };

template <typename T> 
struct Traits<typename S<T>::type> { };

编译器应该如何知道T要插入什么S或者 someS<T>::type是否真的意味着而不是 just int

问题是嵌套的 typedef ( ::type) 依赖于模板参数 ( T)。如果在函数参数列表或部分特化中出现这种情况,T则无法推断类型(它是“非推断上下文”)。

于 2011-06-18T21:24:17.037 回答