Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to efficiently count the number of defined pointers?

Tags:

c++

algorithm

I have the following C++ code:

Some_class * temp1 = findTemp1(...); // returns NULL or a valid pointer
Some_class * temp2 = findTemp2(...); // returns NULL or a valid pointer
Some_class * temp3 = findTemp3(...); // returns NULL or a valid pointer

Now I would like to count how many of these returned a valid pointer (0, 1, 2 or 3).

The only way I can think of is just to test them one by one:

int count = 0;
if (temp1)
   count++;
if (temp2)
   count++;
if (temp3)
   count++;

For 3 pointers, it's not too bad, but it doesn't scale well. Is there a more efficient way assuming I don't redefine the findTempN funcitons (to maybe pass in the counter)?


Thanks a lot for your quick replies! No, I am not going to change the code, I was just wondering what were my other options. I also realized that I cannot be asking for something "scalable" if I am using distinct literals like that to define the 3 pointers. Of course, I didn't think of the things you replied :)

like image 403
Ivan Avatar asked Sep 12 '11 12:09

Ivan


1 Answers

Well, since this is C++ we can go crazy in the quest for terseness... for example:

int count = !!temp1 + !!temp2 + !!temp3;

Update: I probably owe Ivan an explanation of what's going on here.

Assuming temp is any kind of pointer, !temp forces the coercion of the pointer's value to bool (we want to do this) and negates the result (this is a side effect that we do not want). This results in true if the pointer is null and false if the pointer is not null, which is the opposite of what we 'd like. So we add another ! in front to negate the result again.

This leaves us with adding three bool values which coerces them to int and performs the addition, whereupon we have our final result.

You might find it easier to understand the completely equivalent

int count = (bool)temp1 + (bool)temp2 + (bool)temp3;

which I did not use because typing !! is three characters shorter than (bool) (note: you might think that this is a nice trick, but when writing code it is a really bad idea to make decisions based on how many characters you have to type).

The moral of the story is that doing this type of thing can be called either clever or atrocious, depending on who you ask -- but in C++ there has traditionally been high tolerance for atrocities.

Note that if the pointers were in some type of collection to begin with, you could write much better-looking code using std::count_if, e.g.:

bool isNotNull(void* ptr) {
    return ptr != 0;
}

std::vector<Some_class*> vec;
vec.push_back(temp1);
vec.push_back(temp2);
vec.push_back(temp3);

int count = std::count_if(vec.begin(), vec.end(), isNotNull);

See it in action.

Or, as very cleverly suggested by MSalters in the comments, you can lose the isNotNull function by counting the pointers which are 0 and subtracting this from the number of all pointers -- but for this, you will need to somehow know what this number is (easy if they are in a vector):

int count = vec.size() - std::count(vec.begin(), vec.end(), 0);

See it in action.

like image 100
Jon Avatar answered Sep 24 '22 10:09

Jon