equal_range 和 2 重载对“this”指针没有合法转换

Posted

技术标签:

【中文标题】equal_range 和 2 重载对“this”指针没有合法转换【英文标题】:equal_range and 2 overloads have no legal conversion for 'this' pointer 【发布时间】:2014-03-27 11:45:43 【问题描述】:

这是简单的代码

#include <map>

class MyMap : public std::multimap<int*, int*>

    public:
    void foo(const int* bar) const
    
        equal_range(bar);
    
;


int main()

    MyMap myMap;

    int number;
    myMap.foo(&number);

    return 0;

编译失败,报如下错误

error C2663: 'std::_Tree<_Traits>::equal_range' : 2 overloads have no legal conversion for 'this' pointer

我看过很多关于这个错误的话题,似乎是const 的问题。如果我把foo(const int* bar) 变成foo(int* bar),它编译得很好。

问题是,我看不到 foo 内容应该如何改变我的 MyMap 对象。 std::multimap 提出 equal_range 的 const 版本:

http://www.cplusplus.com/reference/map/multimap/equal_range/

我的问题是什么?

谢谢

【问题讨论】:

您知道大多数标准库类都不是为了继承而设计的吗?比如std::multimapdestructor不是virtual,所以不会在MyMap对象的析构中被调用。 【参考方案1】:

检查equal_range的定义:

pair<const_iterator,const_iterator> equal_range (const key_type& k) const;

它期望对key_type:const key_type&amp; k 的持续引用。

您试图提供的是一个指向常量整数的指针:const int* bar

即使两个值都是const,为什么这不起作用?

对整数const int&amp; foo 的常量引用意味着您不能让foo 引用另一个整数,但允许更改所引用整数的值。 指向常量整数const int* foo 的指针意味着您可以让foo 指向另一个整数,但不能更改它所指向的整数的值。

地图实际期望的是const int*&amp; k,但如果您仅提供int*(没有const),地图会自动转换它。

[编辑]

还请注意,即使您将 const int* 更改为 int*foo 函数仍然无法更改 MyMap 对象,因为在您的 foo 函数末尾还有另一个 const。最后的这个 const 将函数声明为常量,这意味着它不能修改执行它的当前对象。如果它试图修改它或调用任何可能修改它的东西,你会得到一个编译器错误。 (免责声明:无论如何都可以从 const 函数中修改类,但这是另一个主题。)

【讨论】:

这很微妙,但我想我明白了。我想做的是key_type='const int*',但由于 const 原则不是类型的一部分,所以不可能这样做。使用简单的int* 的问题是该函数不再保证它不会改变指向的值。我应该如何处理?谢谢【参考方案2】:

如果事实上正确的编译器消息可以给你答案。对于两个重载之一(const 之一):

/usr/local/include/c++/v1/map:1836:41: note: candidate function not viable: 1st argument ('const int *')
      would lose const qualifier

const int* 是指向const int 的指针。该方法需要一个const key_type&amp;,即const int*&amp; 参数,即const 对(非constint* 的引用。

感到困惑时,更喜欢将const int* 写成int const*,这是一回事。然后你会更清楚地看到与const int*&amp; 的区别。

要使您的代码正常工作,请使用 int* 而不是 const int*

【讨论】:

【参考方案3】:

我认为问题与key_type 上的不匹配有关。 一方面,您有一个多重映射,其中key_type=int*,而另一方面您传递了一个key_type=const int*,因此试图将const 限定符放在key_type 上。我也对此感到困惑,因为我在脑海中扩展key_type 以获得应该兼容的const int*&amp;。但是,不匹配发生在 key_type 本身的早期。至少这是我能想到的唯一合乎逻辑的解释。

我的建议是制作 key_type const int* 并保持函数参数不变。毕竟,为什么需要一个指向可变值的指针作为映射的键?

【讨论】:

以上是关于equal_range 和 2 重载对“this”指针没有合法转换的主要内容,如果未能解决你的问题,请参考以下文章

封装 ,this,构造方法,方法重载

Java重载覆写thissuper抽象类接口

使用 `std::equal_range` 和 `boost::transform_iterator`

c++stl之lower_bound,upper_bound和equal_range函数的详细介绍!!!

Java基础——构造器重载 & this关键字

C++类和对象(this指针6个默认成员函数const成员)