为可转换为指针的迭代器专门化一个类
Specializing a class for iterators convertable to pointers
我正在尝试开发一个类,该类将允许我在可以正确执行的情况下通过迭代器语义有效地访问容器/指针,并且当迭代器无法转换为指针时,我希望将迭代器范围复制到临时缓冲区并返回该指针。为此,我编写了以下程序:
#include <cassert>
#include <vector>
#include <deque>
#include <list>
// General case copies data to temporary vector, in case iterators are from a list or otherwise.
template < typename Iterator, typename tag = std::iterator_traits < Iterator >::iterator_category >
class IteratorBuffer
{
typedef typename std::iterator_traits < Iterator >::value_type T;
std::vector < T > temp;
public:
IteratorBuffer(Iterator begin, Iterator end) : temp(std::distance(begin, end))
{
std::copy(begin, end, temp.begin());
}
const T * data() { return temp.data(); }
};
// Special case should be invoked if Iterator can safely be treated as a pointer to the range.
template < typename Iterator >
class IteratorBuffer < Iterator, std::random_access_iterator_tag >
{
typedef typename std::iterator_traits < Iterator >::value_type T;
const T * temp;
public:
IteratorBuffer(Iterator begin, Iterator end) : temp(&*begin) { }
const T * data() { return temp; }
};
int main(int argc, char ** argv)
{
std::vector < int > test1(10);
IteratorBuffer < std::vector < int >::iterator > temp1(test1.begin(), test1.end());
// This should be pointing to the data in test1.
assert(temp1.data() == test1.data());
std::list < int > test2;
for(int i = 0; i < 10; ++i)
test2.push_back(i);
IteratorBuffer < std::list < int >::iterator > temp2(test2.begin(), test2.end());
// This must not point to the beginning iterator.
assert(temp2.data() != &*test2.begin());
int test3[10];
IteratorBuffer < int * > temp3(&test3[0], &test3[10]);
// This should point to the array.
assert(temp3.data() == &test3[0]);
std::deque < int > test4;
for(int i = 0; i < 10; ++i)
test4.push_back(i);
IteratorBuffer < std::deque < int >::iterator > temp4(test4.begin(), test4.end());
// This must not point to the beginning iterator, not safe.
assert(temp4.data() != &*test4.begin());
}
这在上次测试中失败了,因为std::deque的迭代器具有random_access_iterator_tag。
我如何编写这个类,使它在一般情况下正常工作?
我想我应该提到我正在使用VC++2010。
编辑:正如亚当所说(我很害怕),这是不可能的。现在,我正试图定义我自己的特质,使我能够做到这一点。请参阅下面的尝试:
template < typename Iterator >
struct IteratorTraits
{
enum { IsPointerCompatible = false };
typedef typename std::iterator_traits < Iterator >::value_type T;
};
template < typename T >
struct IteratorTraits < T * >
{
enum { IsPointerCompatible = true };
typedef T T;
};
template < typename T >
struct IteratorTraits < const T * >
{
enum { IsPointerCompatible = true };
typedef const T T;
};
//template < typename T >
//struct IteratorTraits < typename std::vector < T >::iterator >
//{
// enum { IsPointerCompatible = true };
// typedef T T;
//};
//template < typename T, size_t N >
//struct IteratorTraits < typename std::array < T, N >::iterator >
//{
// enum { IsPointerCompatible = true };
// typedef T T;
//};
我省略了IteratorBuffer类,因为它们与使用std::iterator_traits的类非常相似。
前两个专业化有效,但有两个注释的特征结构无效。我如何在不依赖于我的特定STL实现的情况下编写这些代码,使其能够工作?
您可以显式地专门化指针,然后专门化任何容器(您所知道的),可以以这种方式处理迭代器(std::vector
就是这样)。这并没有那么糟糕,因为容器没有通用的"特性",即它的迭代器可以用作指针。这是容器提供者必须明确作出的保证。
还要注意的是,IteratorBuffer
的通用版本至少默认为前向迭代器类别,并且在使用仅输入迭代器时会失败(因为它使用了两次范围)。
相关文章:
- 模板函数,其中一个参数需要专门化,而另一个不需要
- 模板通过一个专门化同时接受throw和nothrow
- 专门化一个成员函数,而不是整个类
- 为模板函数专门化一个模板类
- 我可以用非模板类专门化一个可变模板模板模板参数吗
- C++专门化一个模板类以获得一个额外的模板参数
- 为可转换为指针的迭代器专门化一个类
- 标准库实现专门化一个基于子概念的概念模板的函数合法吗
- c++模板函数:显式实例化一个或多个专门化
- 二进制搜索的一个函数模板专门化
- c++:设置一个局部专门化等于另一个
- 如何在具有多个参数类型的模板类中专门化一个方法
- 一个TU中的模板专门化被另一个TU隐藏
- 当试图用另一个类模板部分专门化一个类模板时,在VS2013中出现错误
- 如何知道一个类型是否是std::vector的专门化
- 我可以用别名模板专门化一个类模板吗?
- 另一个模板(同一类的)的模板专门化
- 不能在模板专门化定义中将一个类的成员类型定义用作模板形参
- 无法专门化来自另一个命名空间的模板
- 是否有可能创建一个模板,当专门化时,产生另一个模板