在 C++ 中替换集合的最佳方法 [英] Best way to replace a set in C++

查看:65
本文介绍了在 C++ 中替换集合的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须重构看起来像这样的旧代码(我不是一个非常精通 C++ 的程序员)

I have to refactor old code that looks like this (I am not a very proficient C++ coder)

 std::set<SomeObject>::iterator it = setobject.begin();

 do {
     it->setProperty1ToNextValue();
     it->getProperty2();
     it->getProperty3();
     it++ 
 } while (it != setobject.end());

基本上我想遍历集合的元素并获取和设置/更新它们的一些属性.我无法使用原始集,因为我遇到了此线程中描述的问题该对象具有类型限定符不兼容的成员函数对象类型是 const

Basically I want to iterate through the elements of the set and get and set/update some of their properties. I cant use the original set since I run in the problems described in this thread the object has type qualifiers that are not compatible with the member function object type is const

我正在考虑用出队代替集合(这将涉及一些重写),因为我将能够设置和获取出队的每个元素的属性.这是一个好方法吗?

I am thinking of replacing the set with a dequeue (it will involve some rewriting) since I will then be able to set and get properties on each element of the dequeue. Is this a good approach?

推荐答案

std::set 的工作原理是根据对象的 < 将所有项目按顺序排列操作员.你不能在你的对象上调用非常量方法的原因是因为这些方法可能会改变你的对象 < 操作符返回的值,因此有效地重新排序"引擎盖下的集合std::set 不知道.

A std::set works by keeping all the items in order according to the object's < operator. The reason you cannot call non-const methods on your object is because there is risk that those methods will change the value returned by your objects < operator, and therefore effectively "reorder" the set under the hood without the std::set knowing.

虽然您没有详细说明您要做什么,以便我们为我们提供最佳答案,但这里有几种方法可以从技术上实现在您的集合上调用某些方法.您可以使用 const_cast 来调用您确定不会修改密钥的方法.或者您可以将项目放入向量中,调用可能修改键"的方法,然后将它们放回原始集合中.

While you haven't specified enough of what you are trying to do for us to provide the best answer, here is a couple ways to technically achieve calling some methods on your set. You can use const_cast to call methods you are sure won't modify the key. Or you can put the items in a vector, call methods that might modify the "key", and then put them back in the original set.

// Example program
#include <iostream>
#include <string>
#include <set>
#include <algorithm>

class SomeObject
{
    std::string key;
    int         data;

public:
    SomeObject( const std::string& key_, int data_ ) : key( key_ ), data( data_ )
    {}

    // For a item to be in a set, it must have a "<" operator that tells it how to order it
    bool operator <( const SomeObject& rhs ) const
    {
        return key < rhs.key;   
    }

    void setKey( const std::string& key_ )
    {
        key = key_;   
    }

    void setData( int data_ )
    {
        data = data_;   
    }
};

int main()
{   
     std::set< SomeObject > setobject;
     setobject.insert( SomeObject("c", 1 ) );
     setobject.insert( SomeObject("a", 1 ) );
     setobject.insert( SomeObject("b", 1 ) );

     // internally, the set will keep everything in order "a", "b", "c"

     // option 1 - use const_cast (risky!)
     {
         std::set< SomeObject >::iterator it = setobject.begin();

         do {
             // const_cast< SomeObject& >( *it ).setKey( "d" );  bad idea, now the set is jacked up because its not in the right order
             const_cast< SomeObject& >( *it ).setData( 2 );
             it++;
         } while (it != setobject.end());
     }

     // option 2 - put the items in the vector, call the methods, then put them back in the original set
     {
         std::vector< SomeObject > tempVec( std::begin( setobject ), std::end( setobject ) );
         std::vector< SomeObject >::iterator it = tempVec.begin();
         do {
             it->setKey( "d" ); 
             it->setData( 2 );
             it++;
         } while (it != tempVec.end());

         std::set< SomeObject > newSet( std::begin( tempVec ), std::end( tempVec ) );
         std::swap( newSet, setobject );  // put the new items back in the original setobject
     }



}

这篇关于在 C++ 中替换集合的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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