Shih-Chan Huang
Shih-Chan Huang

Reputation: 209

How to let a set in C++ filter out the different pointers pointing to the same value

As we know, C++ "set" will not allow the same values being inserted.

My question is, how can I apply this to a bunch of pointers, where some of them will point to the same value. Let's just move on to the following example

set<int *> my_set;
int a = 10, b = 20, c = 10;
int *ptr1 = &a, *ptr2 = &b, *ptr3 = &c;
my_set.insert(ptr1);  // Insert successfully
my_set.insert(ptr2);  // Insert successfully
my_set.insert(ptr3);  // Although insert successfully, 
                      // BUT I DON'T WANT ptr3 TO BE INSERTED,
                      // since it points to the same value as ptr1 does

Except checking the contained values one by one, like inserting after iteratively checking the set via a for-loop, are there any ways for me to do what I just mentioned above?

Thanks again!

Upvotes: 1

Views: 281

Answers (1)

Sam Varshavchik
Sam Varshavchik

Reputation: 118340

This is done by using a std::set with a custom comparator that compares the values that each pointer is pointing to. std::set has a 2nd optional template parameter that specifies a custom class that's used for comparing values in the set. Normally it's std::less, i.e., a fancy facade for the < operator. Basically, just specify a custom comparator that defines what < means for the values in your set.

#include <iostream>
#include <set>

struct comparator {

    bool operator()(int * const &a,
            int * const &b) const
    {
        return *a < *b;
    }
};

int main()
{
    std::set<int *, comparator> my_set;

    int a = 10, b = 20, c = 10;
    int *ptr1 = &a, *ptr2 = &b, *ptr3 = &c;
    my_set.insert(ptr1);
    my_set.insert(ptr2);
    my_set.insert(ptr3);

    for (const auto &p: my_set)
    {
        std::cout << *p << std::endl;
    }

    return 0;
}

Upvotes: 1

Related Questions