无论传递了迭代器类型/指针,指向元素的地址

Posted

技术标签:

【中文标题】无论传递了迭代器类型/指针,指向元素的地址【英文标题】:Address of the pointed element whatever the iterator type/pointer is passed 【发布时间】:2012-08-29 13:47:08 【问题描述】:

以下函数最通用的语法是什么:

template<IteratorType> void myFunction(const IteratorType& myIterator)

    _ptr = &myIterator[0];

它接受一个迭代器 myIterator(它可以是一个原始指针),目标是将myIterator 指向的对象的地址分配给一个原始指针_ptr。目前我使用&amp;myIterator[0],但我意识到只有随机访问迭代器才有运算符[]。

那么有没有一种语法适用于所有类型的标准迭代器和指针?

【问题讨论】:

这可能比您在存储元素覆盖operator&amp;... @DavidRodríguez-dribeas: Indeed (尽管这些天我们有std::addressof 而不是那种胡言乱语) 【参考方案1】:

您可以取消引用指针,然后获取对象的地址。

template<IteratorType> void myFunction(const IteratorType& myIterator)

    _ptr = &(*myIterator);

【讨论】:

请注意,如果存储的对象重载operator&amp;,这将失败(是的,你不应该重载operator&amp;,但它在语言中是允许的) &amp;*myIterator 中不需要括号。【参考方案2】:

根据标准 * 运算符返回一个引用,所以我认为最好的方法是 &amp;*myIterator,但由于类可能重载 & 运算符,最好的方法是适用于所有类的 std::addressof(*myIterator)

【讨论】:

+1 表示 std::addressof。如果没有 C++11,可以使用 boost::addressof。 只有转发迭代器承诺返回引用,输入和输出迭代器才能返回代理对象,&amp; 不适合。 你必须保证你应用的任何迭代器都必须是有效的。 IE。一个非结束迭代器。否则......你知道......恶魔。【参考方案3】:

所有迭代器都必须有operator *(24.2.2:2),所以你可以写

_ptr = &*myIterator;

但是,这对于输出迭代器无效,其中*r 仅在赋值操作的左侧有效 (24.2.4:2)。

还请注意,*r 不一定会提供一个可以合理应用&amp; 的值;例如,特化 std::vector&lt;bool&gt; (23.3.7) 的 reference 类型不是 bool &amp;。在您的情况下,赋值 _ptr = &amp;*myIterator 会捕捉到这一点,假设 _ptr 是适当的指针类型,并且您会遇到编译失败。

【讨论】:

您必须保证您应用的任何迭代器都必须是有效的。 IE。一个非结束迭代器。否则......你知道......恶魔。【参考方案4】:

我希望你们现在都还活着。如果您的迭代器是 std::vector 的迭代器,则有更好的方法来获取迭代器所持有的地址。您可以使用:

auto *ptr = myIterator._Ptr;

希望我能正确回答您的问题。

【讨论】:

不幸的是,这不是一个可移植的解决方案。任何以 '_' 开头后跟大写字母的标识符都保留为实现细节,并且不能保证在相同实现的未来版本中保持一致。总之,不要使用它。

以上是关于无论传递了迭代器类型/指针,指向元素的地址的主要内容,如果未能解决你的问题,请参考以下文章

迭代器

C++ 的STL中,迭代器那个指针为何++能指向下一个元素?

迭代器的注意事项

迭代器失效

c++之迭代器

课时10:迭代器迭代器失效分析