简体   繁体   English

在std :: vector迭代器中使用运算符!=时出错

[英]Error using operator != with std::vector iterator

In some legacy code I see the following: 在一些旧代码中,我看到以下内容:

class myClass : public CObject
{
    DECLARE_DYNAMIC(myClass)

public:
    void myClassMethod() const;
    ....
}
std::vector<const myClass*> vMyClass;
...
for (const myClass *const* Q = vMyClass.begin(); Q != vMyClass.end(); Q++)
        (*Q)->myClassMethod();

I don't understand what const is doing here. 我不明白const在这里做什么。 (I can't search for it, either in this forum or in Google, without the asterisks being stripped off, so searching for an explanation is useless.) (无论是在这个论坛还是在Google中,我都无法搜索到它,而不会删除星号,因此搜索说明毫无用处。)

What I do know is that this code generally assumed that vector.begin() returns a pointer rather than an iterator. 我所知道的是,此代码通常假定vector.begin()返回的是指针而不是迭代器。 So I tried rewriting the for loop as: 所以我尝试将for循环重写为:

std::vector<myClass*>::iterator Q;

for (Q = vMyClass.begin(); Q != vMyClass.end(); Q++)
    (*Q)->myClassMethod();

But I get the following error from the Visual Studio 2003 C++ compiler: 但是我从Visual Studio 2003 C ++编译器中收到以下错误:

error C2678: binary '!=' : no operator found which takes a left-hand operand of type 'std::vector<_Ty>::iterator' (or there is no acceptable conversion) with [ _Ty=myClass * ] 错误C2678:二进制'!=':找不到带有[_Ty = myClass *]且类型为'std :: vector <_Ty> :: iterator'的左侧操作数(或没有可接受的转换)的运算符

I don't understand what's going wrong here... In another part of the code I have: 我不明白这里出了什么问题...在代码的另一部分中,我有:

std::vector<myOtherClass> vMyOtherClass;
...
std::vector<myOtherClass>::iterator Z;

for (Z = vMyOtherClass.begin(); Z != vMyOtherClass.end(); ++Z)
    ...

this compiles cleanly. 编译干净。 Any ideas why I get the error on the vMyClass loop or what to do about it? 有什么想法为什么我会在vMyClass循环上收到错误或如何处理? Any idea what const is doing? 知道const在做什么吗?

New Information 新的信息

Originally, I had copied the vector definition incorrectly. 最初,我错误地复制了矢量定义。 Now that it's fixed (above), I see that the iterator was missing a const. 现在它已修复(在上面),我看到迭代器缺少const。 It should read: 它应显示为:

std::vector<const myClass*>::iterator Q;

But when I made this fix in my code, the error message switched from the call to vector.end() to vector.begin(): 但是,当我在代码中进行此修复时,错误消息从调用切换为vector.end()变为vector.begin():

error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::vector<_Ty>::const_iterator' (or there is no acceptable conversion) with [ _Ty=const myClass * ] 错误C2679:二进制'=':找不到带有[_Ty = const myClass *]类型为'std :: vector <_Ty> :: const_iterator'(或没有可接受的转换)的右侧操作数的运算符

I don't get how it could work for vector.end() with operator !=, yet be wrong for vector.begin() with operator =...? 我不知道它如何与带有运算符!=的vector.end()一起工作,但是对于带有运算符= ...的vector.begin()却是错误的?

I don't understand what const is doing here. 我不明白const在这里做什么。

const applies to the thing on its left, unless nothing is there, then it applies to the thing on its right instead. const适用于它左边的东西,除非没有东西,然后它适用于它右边的东西。

Remember that whitespace doesn't matter, so let's make your declaration a little easier to read: 请记住,空格并不重要,因此让您的声明更易于阅读:

const myClass * const * Q

Which is the same as 与...相同

const myClass* const *Q

The first const applies to myClass , and the second const applies to the first * . 第一个const适用于myClass ,第二个const适用于第一个*

Declarations are read in right-to-left order (see Easy rule to read complicated const declarations? ), so this declaration basically says: 声明以从右到左的顺序读取 (请参阅轻松读取复杂的const声明的规则? ),因此该声明基本上说:

"Q is a non-const pointer to a const pointer to a const MyClass object" “ Q是指向const MyClass对象的const指针的非const指针”

Basically, meaning that the value of Q itself can be changed (good for iterating), but the value of the myClass* pointer that Q is pointing at can't be changed, and the myClass object that is being pointed at by the myClass* pointer can't be changed either (only const methods can be called on it). 基本上,这意味着值Q本身可被改变(良好用于重复),但的值myClass*指针Q所指向不能被改变,并且myClass正在由所述指向对象myClass*指针也不能更改(只能在其上调用const方法)。

Below example will clear your doubt regarding const myClass *const* Q : 下面的示例将清除您对const myClass *const* Q疑问:

#include <iostream>
using namespace std;

int main(void)
{
    int i = 10;
    int j = 20;
    int *pt = &j;

    /* constant pointer to constant integer */
    const int *const ptr = &i;  

    /* constant pointer to constant poniter */
    const int *const * pptr = &pt;  

    cout<< " Address of i :" << &i << "    Address of J : " << &j <<endl;
    cout<< " value of i :  " << i << "    value of J : " << j << endl;
    cout<<" pptr :   " << pptr << endl;
    cout<<" ptr  :   " << ptr << endl;  // ptr is point to i
    cout<<" *pptr :   " << *pptr << endl; // *pptr is pointing j
    cout<<" *ptr  :   " << *ptr << endl;
    cout<<" **pptr :   " << (*(*pptr)) << endl;

    return 0;
}

Output :: 输出::

Address of i :0x22fe3c    Address of J : 0x22fe38
value of i :  10    value of J : 20
pptr :   0x22fe30
ptr  :   0x22fe3c
*pptr :   0x22fe38
*ptr  :   10
**pptr :   20

Hope you are clear now. 希望你现在明白了。

What I do know is that this code generally assumed that vector.begin() returns a pointer rather than an iterator 我所知道的是,这段代码通常假定vector.begin()返回的是指针而不是迭代器

You are wrong here, it returns an iterator. 您在这里错了,它返回一个迭代器。 Please refer to vector::begin() reference . 请参考vector :: begin()参考

(check your myClassMethod function ( (*Q)->myClassMethod(); ) ) and refer to error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const Recipe' (or there is no acceptable conversion) (检查您的myClassMethod函数( (*Q)->myClassMethod(); )),并参考错误C2678:二进制'=':未找到采用'const Recipe'类型的左操作数的运算符(或者没有可接受的转换)

My suggestion : use latest C++11/C++14 feature (Like auto , ...). 我的建议:使用最新的C ++ 11 / C ++ 14功能(例如auto ,...)。

You actually have const in two places, with somewhat different effects. 实际上,您在两个地方都有const ,但效果有所不同。

for (const myClass *const* Q = vMyClass.begin(); Q != vMyClass.end(); Q++)
     ^^1^^          ^^2^^

First, let's separate out the declaration from the rest: 首先,让我们将声明与其他声明分开:

const myClass *const* Q

Let's start by making this consistent, and putting each const after what it modifies. 首先,使它保持一致,然后将每个const放在修改后的位置。 In this case, that means moving only the first one: 在这种情况下,这意味着仅移动第一个:

myClass const *const* Q

For a declaration like this, we want to start from the name of the object being declared, and read "*" as "pointer to a", so this is read as something like this: 对于这样的声明,我们要从要声明的对象的名称开始,并将“ *”读为“指向a的指针”,因此应将其读为以下内容:

 Q is a pointer to a const pointer to a const myClass

The problem you have doesn't really relate to const at all. 您遇到的问题与const根本无关。 The problem you have is that the author of the code depended on the fact that in some particular library, std::vector<T>::iterator was (apparently) implemented as a pointer to T. This is allowable, but has some undesirable side effects (eg, it means vector<derived>::iterator can be implicitly converted to vector<base>::iterator ) so modern implementations generally avoid it. 您遇到的问题是,代码的编写者依赖于这样的事实:在某些特定的库中, std::vector<T>::iterator (显然)被实现为指向T的指针。副作用(例如,它意味着vector<derived>::iterator可以隐式转换为vector<base>::iterator ),因此现代实现通常会避免它。

If you want to convert this code to modern C++, all that is sort of beside the point though--you probably want to use something like this: 如果您想将此代码转换为现代C ++,那么所有这些都不是重点-您可能想使用如下代码:

for (auto Q : vMyClass)
    Q->myClassMethod();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 错误:对于操作数类型 std::vector::iterator 和 __gnu_cxx::__normal_iterator 不匹配“operator=” - error: no match for 'operator=' for operand types std::vector::iterator and __gnu_cxx::__normal_iterator 反向迭代器错误:&#39;rcit!= std :: vector &lt;_Tp,_Alloc&gt; :: rend()中的&#39;operator!=&#39;与_Tp = int,_Alloc = std :: allocator&#39;不匹配 - reverse iterator error : no match for 'operator!=' in 'rcit != std::vector<_Tp, _Alloc>::rend() with _Tp = int, _Alloc = std::allocator' 使用向量迭代器的&#39;operator =&#39;不匹配 - no match for ‘operator=’ using iterator for a vector 推进std :: vector std :: advance VS运算符+的迭代器? - Advance iterator for the std::vector std::advance VS operator +? 错误:没有匹配的 function 调用 'recherche(std::vector &gt;&amp;, std::vector &gt;::iterator, std::vector &gt;::iterator, const char [10])' - error: no matching function for call to ‘recherche(std::vector >&, std::vector >::iterator, std::vector >::iterator, const char [10])’ 不匹配operator =使用std :: vector - no match for operator= using a std::vector 在空std :: vector上使用operator [] - Using operator[] on empty std::vector C ++模板std :: vector :: iterator错误 - C++ template std::vector::iterator error 对std :: vector :: iterator使用vs. typedef - using vs. typedef for std::vector::iterator 迭代器使用end()持续std :: vector的元素 - - Iterator to last element of std::vector using end()--
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM