C++ 如何创建操作员->;在没有容器的迭代器中? 模板 类枚举迭代器{ 公众: 常量枚举*运算符->()常量{ return&(Enum::OfInt(i));//警告:正在获取临时 } 常量枚举运算符*()常量{ 返回Enum::OfInt(i);//这个没有问题! } 私人: int i; };
我得到上面的警告。目前,我正在使用此黑客:C++ 如何创建操作员->;在没有容器的迭代器中? 模板 类枚举迭代器{ 公众: 常量枚举*运算符->()常量{ return&(Enum::OfInt(i));//警告:正在获取临时 } 常量枚举运算符*()常量{ 返回Enum::OfInt(i);//这个没有问题! } 私人: int i; };,c++,pointers,iterator,C++,Pointers,Iterator,我得到上面的警告。目前,我正在使用此黑客: 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:
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;
};
模板
类枚举迭代器{
公众:
常量枚举*运算符->(){
tmp=Enum::OfInt(i);
返回&tmp;
}
私人:
int i;
Enum tmp;
};
但这很难看,因为迭代器充当丢失的容器
迭代值范围的正确方法是什么
更新:
迭代器专用于支持命名静态构造函数OFIT(代码段更新)的特定集合对象
请不要挑剔我粘贴的代码,只是要求澄清。我试着提取一个简单的片段
如果您想知道T将是强枚举类型(本质上是打包到类中的int)。将有typedef EnumIterator使用运算符*更新了代码,没有问题。迭代器在特定容器上进行迭代。实现取决于它是什么类型的容器。返回的指针应指向该容器的成员。您不需要复制它,但您确实需要跟踪您正在迭代的容器,以及您所在的位置(例如向量的索引),这可能是在迭代器的构造函数中初始化的。或者只使用STL。有很多种迭代器 例如,在向量上,迭代器通常是普通指针:
template <class Enum>
class EnumIterator {
public:
const Enum* operator-> () {
tmp = Enum::OfInt(i);
return &tmp;
}
private:
int i;
Enum tmp;
};
模板
类迭代器
{
公众:
T*运算符->(){返回m_指针;}
私人:
T*m_指针;
};
但这是可行的,因为向量实际上只是一个数组
在双链接列表上,情况会有所不同,该列表将由节点组成
template <class T>
class Iterator
{
public:
T* operator->() { return m_pointer; }
private:
T* m_pointer;
};
模板
结构体类型
{
节点*m_prev;
Node*m_next;
T m_值;
};
模板
类迭代器
{
公众:
T*运算符->(){返回m_节点->m_值;}
私人:
节点*m_节点;
};
通常,您希望迭代器尽可能轻,因为迭代器是通过值传递的,所以指向底层容器的指针是有意义的
您可能需要添加额外的调试功能:
- 使迭代器无效的可能性
- 射程检查可能性
- 容器检查(即,在比较引用同一容器的两个迭代器时进行检查)
不过,如果您有一个静态向量,那么就可以简单地重用向量迭代器。它返回什么?在这种情况下,它似乎返回了错误的类型。它应该返回一个T*,而似乎是返回一个T值,然后取它的地址。这可能会产生不正确的行为,因为它将丢失通过->进行的任何更新
template <class T>
struct Node
{
Node* m_prev;
Node* m_next;
T m_value;
};
template <class T>
class Iterator
{
public:
T* operator->() { return m_node->m_value; }
private:
Node<T>* m_node;
};
问题不在于它丑陋,而在于它不安全。发生了什么,例如在如下代码中:
Enum* operator-> () {
tmp = Enum::OfInt(i);
return &tmp;
}
现在g()
以两个指针结束,这两个指针都指向同一个内部临时对象,该内部临时对象应该是迭代器的实现细节。如果g()
通过一个指针写入,则另一个值也会更改。哎哟
你的问题是,这个函数应该返回一个指针,但是你没有指向的对象。不管怎样,你都必须解决这个问题
我认为有两种可能性:
枚举
,并且枚举类型没有成员,所以操作符->
无论如何都是无用的(除非调用它,否则它不会被实例化,并且不能被调用,因为这将导致编译时错误),并且可以安全地忽略它李>
Enum::Enum_type
),仅当您希望对其执行类似整数的操作(例如,增量)时,才将其转换为int
李>
由于没有容器,我决定将迭代器合并到我的强枚举中。 我将raw int初始化为-1,以支持空枚举(limit==0),并能够将正则for循环与TryInc一起使用 代码如下:
void f(EnumIterator it)
{
g(*it, *it);
}
模板
类枚举{
公众:
静态常数kLimit=极限;
枚举():原始(-1){
}
bool TryInc(){
if(原始+1原始=原始;
}
raw的静态枚举(uint raw){
返回枚举(原始);
}
布尔运算符==(常量枚举和其他)常量{
返回this->raw==other.raw;
}
布尔运算符!=(常量枚举和其他)常量{
返回此->原始!=其他.raw;
}
受保护的:
显式枚举(uint raw):原始(raw){
}
私人:
未加工的;
};
用法:
template <uint limit>
class Enum {
public:
static const uint kLimit = limit;
Enum () : raw (-1) {
}
bool TryInc () {
if (raw+1 < kLimit) {
raw += 1;
return true;
}
return false;
}
uint GetRaw() const {
return raw;
}
void SetRaw (uint raw) {
this->raw = raw;
}
static Enum OfRaw (uint raw) {
return Enum (raw);
}
bool operator == (const Enum& other) const {
return this->raw == other.raw;
}
bool operator != (const Enum& other) const {
return this->raw != other.raw;
}
protected:
explicit Enum (uint raw) : raw (raw) {
}
private:
uint raw;
};
类颜色:公共枚举{
公众:
静态常数为红色;
//构造函数应自动转发。。。
颜色():枚举(){
}
私人:
颜色(uint原始):枚举(原始){
}
};
常量颜色::红色=
class Color : public Enum <10> {
public:
static const Color red;
// constructors should be automatically forwarded ...
Color () : Enum<10> () {
}
private:
Color (uint raw) : Enum<10> (raw) {
}
};
const Color Color::red = Color(0);
int main() {
Color red = Color::red;
for (Color c; c.TryInc();) {
std::cout << c.GetRaw() << std::endl;
}
}