C++ 当取消引用(运算符*)按值返回时,箭头运算符(运算符->;)返回类型

C++ 当取消引用(运算符*)按值返回时,箭头运算符(运算符->;)返回类型,c++,iterator,C++,Iterator,我正在编写一个InputIterator,它实现了操作符*和操作符-> My运算符*返回对(向量)元素的一对引用。运算符*因此按值返回 根据参考资料: 运算符->的重载必须返回原始指针,或返回运算符->依次重载的对象(通过引用或通过值) 那我该怎么办 我不能返回原始指针;这一对必须以某种方式归还。 那么可能是某个定义了操作符->的包装器?它是否存在于标准库中,或者通常是如何实现的?模板 template<class T> struct fake_ptr_with_value {

我正在编写一个InputIterator,它实现了操作符*和操作符->

My运算符*返回对(向量)元素的一对引用。运算符*因此按值返回

根据参考资料:

运算符->的重载必须返回原始指针,或返回运算符->依次重载的对象(通过引用或通过值)

那我该怎么办

我不能返回原始指针;这一对必须以某种方式归还。 那么可能是某个定义了操作符->的包装器?它是否存在于标准库中,或者通常是如何实现的?

模板
template<class T>
struct fake_ptr_with_value {
  T t;
  T* operator->() { return std::addressof(t); }
};
带值的结构伪\u ptr\u{ T; T*运算符->(){return std::addressof(T);} };
返回一个带有值的
伪\u ptr\u

std
中未公开此类助手类型

请注意,由于各种迭代器类所需的规范中存在缺陷,这仅适用于
inputierator
s。根据标准,前向迭代器(以及所有更强大的迭代器,如随机访问迭代器)要求
操作符*
返回对真实稳定对象的引用

缺陷在于标准(a)在某些情况下需要引用,而伪引用可以,(b)混合了“迭代”和“取消引用”语义

Rangesv3有一个更解耦的迭代器类别系统,可以解决其中的一些(如果不是全部的话)缺陷

因为这个问题是关于输入迭代器的,所以这个解决方案就足够了;我只是想提醒一下,万一有人想在其他地方使用这种技术。您的代码可能会编译并似乎有效,但当您将迭代器传递给任何<代码> STD< /Cuff>函数时,几乎肯定会违反C++标准的要求,这意味着程序不正确,不需要诊断。

< P>因为您的代码可以为嵌入在其中的一对返回一个代理,即:

template<class T1, class T2>
class pair_proxy {
    std::pair<T1,T2> p;
public:
    pair_proxy(const std::pair<T1,T2>& p) : p(p) {}
    std::pair<T1,T2>* operator->() { return &p; }
};
模板
类对代理{
std::对p;
公众:
pair_代理(const std::pair&p):p(p){}
std::pair*运算符->(){return&p;}
};

<强>注:我强烈考虑在迭代器中嵌入<代码> STD::配对< /代码>,并从您的<代码>运算符>()实现中返回一个指针。

我认为我可以返回一个包装器,它将保持该值作为数据成员,并将定义一个运算符>将指针返回到它的数据成员。但它是否存在于std库中?使用
std::pair
或soBut迭代器类或结构应该已经是一个“包装器”,它引用“容器”中的元素。迭代器最简单的解决方案是包含当前位置,从中可以得到被引用的“值”(“对象”)。然后很容易返回一个指向引用元素的指针。作为一个粗略的规则,如果类'
操作符*()
(取消引用)返回的是一个值而不是一个引用,那么应该质疑它是否应该有一个
操作符->()
。习惯上,
object->a
(*object)。a
通常是对同一实体的引用(或值),如果
操作符*()
按值返回,则实现这一点相当复杂,有时是不可能的。@Someprogrammerdude这不是我的情况,但是,如果向量中有更多的迭代器,例如,并按顺序处理它们,则存储值类型的迭代器将占用过多的空间,而不是迭代器在取消引用时返回包装器/代理/->。嵌入必须是
前向迭代器
。(这有点不幸,因为对于许多类型,即使使用by value
operator*
)和当有人执行时,也可以高效地编写多遍算法他们有一个悬垂的参照物?@ayxan是的,他们在那里做了一个悬垂的参照物。这是输入迭代器的限制之一;您不能保证对象长期存在。
*
->
有趣的是,
自动常量&ref=*It
是可以的,但是
自动常量&foo=It->foo
是悬空的。我确实理解原因,但这有点骗人。@Ayxan等到你玩
(*it).foo
。使用
decltype(std::addressof(t))操作符->(
)不是更好吗?