通过引用c ++传递非常量迭代器指向的值

Posted

技术标签:

【中文标题】通过引用c ++传递非常量迭代器指向的值【英文标题】:Pass value pointed by non-const iterator by reference c++ 【发布时间】:2014-06-26 06:51:17 【问题描述】:

我有一个 std::set<MyType> 容器,我是通过某个类的 get 函数获得的,即我有这样的东西:

typedef std::set<MyType, compareMyType> MyTypeSet;  
// this a singleton class
class MyClass   
...  
public:  
    MyTypeSet& getMySet()  return mySet_;   
...  
private:  
MyTypeSet mySet_;  
...  
  

然后在其他地方我正在使用这个容器:

MyClass obj;
MyTypeSet& mySet = mtyObj->getMySet();
MyTypeSet::iterator itBeg = mySet.begin();
// Then I'm trying to call f function
f(*itBeg);

其中 f 函数的签名如下:

void f(MyType& param);

我收到这样的编译错误:

note: candidates are: void f(MyType&)
error: no matching function for call to f(const MyType&)

我该如何解决这个问题? 提前致谢。

【问题讨论】:

mtyObj 是指向 const 对象的指针吗? 不,它不是 const,@Pradhan。 【参考方案1】:

在不了解您的环境的详细信息的情况下,我猜测您的系统对 set 的实现尝试通过将 iterator 别名为 const_iterator 来“安全”(这样您就不会尝试通过迭代器,这很危险,因为它可能会改变排序顺序)。有关更多信息,请参阅here。

如果是这样,那么最简单的解决方法就是按照编译器的建议将函数的签名更改为 void f(const MyType&amp; param)。如果您确实需要修改参数(以不会改变排序顺序的方式),有多种技巧可以绕过const 限制(包括使用@987654327 @ 或上述链接中建议的解决方案),但我建议谨慎行事。

【讨论】:

谢谢@Turix,我确实需要修改f函数中的param值,所以,也许我会使用const_cast @Heghine,正如 Turix 答案中的链接所示,修改集合中元素的值通常是一个坏主意,因为它可能会破坏集合不变量。如果您确定对 param 所做的修改不会影响排序,也许您可​​以简单地使该部分可变并保留函数签名 const? @Pradhan,你的意思是MyClass?我认为问题不存在。问题出在f 函数签名/调用中。 @Heghine 我的意思是MyType。你说需要修改f中的paramset::begin 最终返回 const 的原因是修改已插入 set 的值可能会破坏由其数据结构(红黑树,iirc)维护的不变量。但是,如果fparam 的修改不会影响params 在set 中的位置,则可以使MyType 的相关部分可变,并且仍然将param 传递到由const 参考。这将确保f 的未来修订版不会意外破坏set @Pradhan,感谢您的澄清。我已经尝试了你的建议,它的工作!我认为这比使用const_cast 更好。

以上是关于通过引用c ++传递非常量迭代器指向的值的主要内容,如果未能解决你的问题,请参考以下文章

通过引用传递 C++ 迭代器有啥问题?

装饰器生成式迭代器

传递迭代器值而不是引用函数

无论传递了迭代器类型/指针,指向元素的地址

如何通过索引自定义 sklearn 交叉验证迭代器?

《C++Primer(第5版)》第十章笔记