template <class Enum>
class EnumIterator {
public:
const Enum* operator-> () const {
return &(Enum::OfInt(i)); // warning: taking address of temporary
}
const Enum operator* () const {
return Enum::OfInt(i); // There is no problem with this one!
}
private:
int i;
};
我在上面收到了这个警告。目前我正在使用这个 hack:
template <class Enum>
class EnumIterator {
public:
const Enum* operator-> () {
tmp = Enum::OfInt(i);
return &tmp;
}
private:
int i;
Enum tmp;
};
但这很丑陋,因为迭代器充当了缺失的容器。
迭代值范围的正确方法是什么?
更新: 迭代器专用于支持命名静态构造函数 OfInt 的特定集合对象(已更新代码片段)。
请不要对我粘贴的代码挑剔,而只是要求澄清。我试图提取一个简单的片段。
如果你想知道 T 将是强枚举类型(本质上是一个 int 包装到一个类中)。就会有typedef EnumIterator < EnumX > Iterator;在 EnumX 类中。
更新 2: 添加的常量表示将通过 -> 访问的强枚举类的成员不会更改返回的临时枚举。
用 operator* 更新了代码,这没有问题。
最佳答案
Enum* operator-> () {
tmp = Enum::OfInt(i);
return &tmp;
}
问题不在于它丑陋,而在于它不安全。会发生什么,例如在如下代码中:
void f(EnumIterator it)
{
g(*it, *it);
}
现在 g()
以两个指针结束,这两个指针都指向同一个内部临时对象,它应该是迭代器的实现细节。如果 g()
通过一个指针写入,另一个值也会改变。哎哟。
你的问题是,这个函数应该返回一个指针,但你没有指向的对象。无论如何,你都必须解决这个问题。
我看到了两种可能性:
- 因为这个东西似乎包装了一个
enum
,而枚举类型没有成员,所以那个operator->
无论如何也没用(它不会被实例化除非被调用,并且不能调用它,因为这会导致编译时错误)并且可以安全地省略。 - 在迭代器中存储正确类型的对象(类似于
Enum::enum_type
),并将其转换为int
仅当您想对其执行类似整数的操作(例如,递增)时。
关于c++ - 如何在没有容器的情况下在迭代器中创建运算符->?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1631247/