简体   繁体   English

通用迭代器/指针初始化

[英]Generic iterator/pointer initialization

I have a C++ class Finder that stores a location in containers plus some additional data. 我有一个C ++类Finder ,它在容器中存储一个位置以及一些额外的数据。 Such containers have the type std::string but also char * or MyString . 此类容器的类型为std::string但也包含char *MyString Say, the class looks like this ( Iterator<TContainer>::Type is a trait / metafunction that returns the iterator type for a given container): 说,该类看起来像这样( Iterator<TContainer>::Type是一个特征/元函数,它返回给定容器的迭代器类型):

template <typename TContainer>
class Finder
{
public:
  typedef typename Iterator<TContainer>::Type TIterator;
  TIterator iterator;

  // Initialization of iterator: How to do it generically?

  // Finder {}                       // problem with pointers!
  // Finder() : iterator(0) {}       // problem with iterators!
};

The main problem now is how to initialize the iterator that can be a pointer or an iterator. 现在的主要问题是如何初始化可以是指针或迭代器的迭代器。 If I only wanted to support my own containers then I could simply implement a constructor that takes nullptr_t following the nullptr idiom . 如果我只想支持我自己的容器,那么我可以简单地实现一个构造函数,该构造函数在nullptr惯用法之后采用nullptr_t However, since I want to support pointers, my own iterators and STL iterators, I'm a bit out of depth here. 但是,既然我想支持指针,我自己的迭代器 STL迭代器,我在这里有点不太深入。

The best thing that I can imagine is to write a getNil<>() function, eg the code below. 我能想象的最好的事情是编写一个getNil<>()函数,例如下面的代码。 However, now at least three questions arise: 但是,现在至少出现三个问题:

  1. Is this the best way to achieve my aim? 这是实现目标的最佳方式吗?

  2. How to determine whether a type is a STL iterator? 如何确定类型是否为STL迭代器? I would probably need some #if s, and tailor code to each compiler/STL version to use. 我可能需要一些#if ,并为每个编译器/ STL版本定制代码以供使用。

  3. Is it possible at all to get a nil iterator in the STL? 是否有可能在STL中获得nil迭代器? Is the result of xy in std::vector<int> x, y; int x = xy; std::vector<int> x, y; int x = xy;xy的结果std::vector<int> x, y; int x = xy; std::vector<int> x, y; int x = xy; defined at all? 根本定义?

The code: 编码:

// Forward declaration.
template <typename T>
T getNil<T>();

template <typename TValue> TValue * getNil<TValue *>()
{ return NULL; }

template <typename TValue> TValue * const getNil<TValue * const>()
{ return NULL; }

template <> TValue * const getNil<MyIterator>()
{ return MyIterator(nullptr); }  // nullptr from above idiom

template <> TStlIterator
boost::enable_if<
    MagicallyDetermineIfIsStlIterator<TStlIterator>::value,
    TStlIterator>
getNil<TStlIterator>()
{ return MyIterator(nullptr); }  // nullptr from above idiom
Finder() : iterator() { }

Should do the trick. 应该做的伎俩。 Not providing an argument for a member in the initialization list will call the default constructor on a type that has one, and will zero-initialize POD types including pointers (and it will fail if the type has no default constructor, but that seems unlikely given your scenario). 不为初始化列表中的成员提供参数将在具有一个的类型上调用默认构造函数,并将零初始化包括指针的POD类型(如果类型没有默认构造函数,它将失败,但这似乎不太可能给出您的情况)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM