在不可复制地图的地图迭代器上不支持等式运算符(==) [英] Equality operator (==) unsupported on map iterators for non-copyable maps

查看:280
本文介绍了在不可复制地图的地图迭代器上不支持等式运算符(==)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我有一个不可复制对象的地图,为什么我不能比较迭代器使用==?我想象它不需要复制(或移动)实际的对象,当对迭代器进行平等测试。

  #include < iostream> 
#include< utility>
#include< map>

using namespace std;

class A {
private:
int i;
public:
A(int i):i(i){}
A(A&)= delete;
A(A& a):i(a.i){}
〜A(){}
A& operator =(A&)= delete;

bool operator ==(const A& a)const {return i == a.i; }
};

int main(){
map< int,A> myMap;

map< int,A> :: iterator it = myMap.find(1);
cout<< (it == myMap.end())<< endl;
}

此示例无法编译, c $ c> cout 。



g ++会出现此错误:

  / usr / include / c ++ / 4.8.2 / bits / stl_pair.h:在实例化'struct std :: pair< const int,A>':
test2.cpp:24 :27:required from here
/usr/include/c++/4.8.2/bits/stl_pair.h:127:17:error:'constexpr std :: pair< _T1,_T2> :: pair(const std :: pair< _T1,_T2>&)[with _T1 = const int; _T2 = A]'声明为接受const引用,但隐式声明将采取非const
constexpr pair(const pair&)= default;

clang ++发生此错误:

  / usr / bin /../ lib64 / gcc / x86_64-unknown-linux-gnu / 4.8.2 /../../../../ include / c ++ / 4.8。 2 / bits / stl_pair.h:127:17:error:这个显式默认的拷贝构造函数的参数是const,但是成员或者base需要它是非const 
constexpr pair(const pair&默认;
^
test2.cpp:24:14:note:在实例化模板类'std :: pair< const int,A>'request here
cout< (it == myMap.end())<< endl;

但是,如果 map< int,int> code>而不是 map< int,A> 。使用 const map map< int,A> :: const_iterator / p>

我尝试在 cppreference ,(map :: iterator是一个BidirectionalIterator,它是一个ForwardIterator,它是一个InputIterator),但网站对概念中的确切类型签名含糊不清。

解决方案

问题是你的删除方法使A不可复制...

  #include< iostream> 
#include< utility>
#include< map>

using namespace std;

class A {
private:
int i;
public:
A(int i):i(i){}
// A(A&)= delete;应该是...
A(const A&)= delete;
A(A& a):i(a.i){}
〜A(){}
// A& operator =(A&)= delete;应该是...
A& operator =(const A&)= delete;

bool operator ==(const A& a)const {return i == a.i; }
};

int main(){
map< int,A> myMap;

map< int,A> :: iterator it = myMap.find(1);
cout<< (it == myMap.end())<< endl;
}

使用gcc / g ++验证4.6.3



从复制构造函数和赋值运算符中删除const导致我的编译器给出您收到的相同错误。



必须查找详细信息/引用,为什么这些被声明为这种方式,但复制构造函数和赋值操作符总是采用一个const引用(有意义,因为您的实例被分配的值不应该被方法修改)。


When I have a map of non-copyable objects, why can't I compare the iterators using ==? I would imagine it does not need to copy (or move) the actual objects when doing equality testing on the iterators.

#include <iostream>
#include <utility>
#include <map>

using namespace std;

class A {
private:
    int i;
public:
    A(int i) : i(i) {}
    A(A&) = delete;
    A(A&& a) : i(a.i) {}
    ~A() {}
    A& operator=(A&) = delete;

    bool operator==(const A& a) const { return i == a.i; }
};

int main() {
    map<int, A> myMap;

    map<int, A>::iterator it = myMap.find(1);
    cout << (it == myMap.end()) << endl;
}

This example fails to compile, giving an error on the line with the cout.

g++ gives this error:

/usr/include/c++/4.8.2/bits/stl_pair.h: In instantiation of ‘struct std::pair<const int, A>’:
test2.cpp:24:27:   required from here
/usr/include/c++/4.8.2/bits/stl_pair.h:127:17: error: ‘constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const int; _T2 = A]’ declared to take     const reference, but implicit declaration would take non-const
   constexpr pair(const pair&) = default;

clang++ gives this error:

/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/bits/stl_pair.h:127:17: error: the parameter for this explicitly-defaulted copy constructor is const, but a member or base requires it to be non-const
      constexpr pair(const pair&) = default;
                ^
test2.cpp:24:14: note: in instantiation of template class 'std::pair<const int, A>' requested here
        cout << (it == myMap.end()) << endl;

However, it does work if a map<int, int> is used instead of a map<int, A>. Using a const map<int, A> with map<int, A>::const_iterator does not help.

I tried looking up the exact signature of map::iterator::operator== on cppreference, (map::iterator is a BidirectionalIterator, which is a ForwardIterator, which is an InputIterator) but the website is vague about the exact type signatures in the concepts.

解决方案

The problem is with your deleted methods to make A noncopyable ...

#include <iostream>
#include <utility>
#include <map>

using namespace std;

class A {
private:
    int i;
public:
    A(int i) : i(i) {}
    // A(A&) = delete; should be ...
    A(const A&) = delete;
    A(A&& a) : i(a.i) {}
    ~A() {}
    // A& operator=(A&) = delete; should be ...
    A& operator=(const A&) = delete;

    bool operator==(const A& a) const { return i == a.i; }
};

int main() {
    map<int, A> myMap;

    map<int, A>::iterator it = myMap.find(1);
    cout << (it == myMap.end()) << endl;
}

Verified this with gcc/g++ 4.6.3

Removing the "const" from the copy constructor and the assignment operator caused my compiler to give the same error which you received.

I would have to look up the details/references as to why those are declared that way, but the copy constructor and the assignment operator always take a const reference (make sense as the value to which your instance is being assigned should not be modified by the method).

这篇关于在不可复制地图的地图迭代器上不支持等式运算符(==)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆