无论传递了迭代器类型/指针,指向元素的地址
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
。目前我使用&myIterator[0]
,但我意识到只有随机访问迭代器才有运算符[]。
那么有没有一种语法适用于所有类型的标准迭代器和指针?
【问题讨论】:
这可能比您在存储元素覆盖operator&
...
@DavidRodríguez-dribeas: Indeed (尽管这些天我们有std::addressof
而不是那种胡言乱语)
【参考方案1】:
您可以取消引用指针,然后获取对象的地址。
template<IteratorType> void myFunction(const IteratorType& myIterator)
_ptr = &(*myIterator);
【讨论】:
请注意,如果存储的对象重载operator&
,这将失败(是的,你不应该重载operator&
,但它在语言中是允许的)
&*myIterator
中不需要括号。【参考方案2】:
根据标准 * 运算符返回一个引用,所以我认为最好的方法是 &*myIterator
,但由于类可能重载 & 运算符,最好的方法是适用于所有类的 std::addressof(*myIterator)
【讨论】:
+1 表示 std::addressof。如果没有 C++11,可以使用 boost::addressof。 只有转发迭代器承诺返回引用,输入和输出迭代器才能返回代理对象,&
不适合。
你必须保证你应用的任何迭代器都必须是有效的。 IE。一个非结束迭代器。否则......你知道......恶魔。【参考方案3】:
所有迭代器都必须有operator *
(24.2.2:2),所以你可以写
_ptr = &*myIterator;
但是,这对于输出迭代器无效,其中*r
仅在赋值操作的左侧有效 (24.2.4:2)。
还请注意,*r
不一定会提供一个可以合理应用&
的值;例如,特化 std::vector<bool>
(23.3.7) 的 reference
类型不是 bool &
。在您的情况下,赋值 _ptr = &*myIterator
会捕捉到这一点,假设 _ptr
是适当的指针类型,并且您会遇到编译失败。
【讨论】:
您必须保证您应用的任何迭代器都必须是有效的。 IE。一个非结束迭代器。否则......你知道......恶魔。【参考方案4】:我希望你们现在都还活着。如果您的迭代器是 std::vector
的迭代器,则有更好的方法来获取迭代器所持有的地址。您可以使用:
auto *ptr = myIterator._Ptr;
希望我能正确回答您的问题。
【讨论】:
不幸的是,这不是一个可移植的解决方案。任何以 '_' 开头后跟大写字母的标识符都保留为实现细节,并且不能保证在相同实现的未来版本中保持一致。总之,不要使用它。以上是关于无论传递了迭代器类型/指针,指向元素的地址的主要内容,如果未能解决你的问题,请参考以下文章