PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Monday, November 7, 2022

[FIXED] How can i compare two properties of struct in a single SET?

 November 07, 2022     c++, compare, operator-overloading, set     No comments   

Issue

My code is as below. I have as struct ABC and i have set g_ABCSet to compare the id.

struct ABC
{
CString name;
byte id[2];
}

typedef shared_ptr<ABC> ABC_PTR;

std::set<ABC_PTR, CompareABC> g_ABCSet;

class ComparePager{
public:
    bool operator()(const ABC_PTR& m1, const ABC_PTR& m2) const {
        if (m1->id[0] == m2->id[0]){
            return m1->id[1] < m2->id[1];
        }
        return m1->id[0] < m2->id[0];
    }
}

I try to search in set as below comparing the id

static ABC_PTR ABCptr(new ABC);
//Assume ABCptr have some valid ID 
auto it = g_ABCSet.find(ABCptr);
if (it == g_ABCSet.end())
 {
//not found
}
else
{
 //found one
}

My query here is can i use the same set to compare the "Cstring name" in the ABC struct.

If YES HOW ??

IF NO , DO i need to make same new set ,overlaod operator to comparing Cstring and insert all same pointers to new set also ??


Solution

No you cannot use a single std::set.

Why: Because the set requires the keys to be in 'strict ordering'. Most likely the set uses a tree structure to store it's items and the tree is sorted by the given comparator.

This means also that if you insert multiple items with different names and identical ids, only one items is stored at all (because the Comparator says they are all identical)

You can use std::find_if to search for Cstring name:

CString searchName = "...";
auto it = std::find_if(
  g_ABCSet.begin(), 
  g_ABCSet.end(), 
  [&](const ABC_PTR& ptr) {
     return ptr->name == searchName;
  });

If you have a large set of items in g_ABCSet you should do as you wrote: create a second set with a Comparator for 'name'.

Tip: If you use std::array<byte, 2> id instead of byte id[2] your Comparator could be as simple as

class ComparePager{
public:
    bool operator()(const ABC_PTR& m1, const ABC_PTR& m2) const {
        return m1->id < m2->id;
    }
}

Maybe you better use a std::map<std::array<byte, 2>, ABC_PTR> and another std::map<CString, ABC_PTR> for this job. This needs more memory (mostly because of the CString being copied from the g_ABCSet into the map) but get completly rid of the custom Comparators and you cannot accidentally use the wrong set (with the wrong Comparator)



Answered By - Andreas H.
Answer Checked By - Katrina (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing