2

Good day everyone,

I have been trying the following code to reset all pointers in a list to nullptr as shown below:

    for (auto item : { ptr1, ptr2, ptr3 })
        item = nullptr;

the problem is that a copy of the pointer is made to item, so the original ptrs are unequal to nullptr at the end.

I would like to get some sort of reference to the pointers themselves or maybe there is already a better alternative to setting all pointers in a container to nullptr. If any of you happen to work with Qt maybe there's a good way of doing it in Qt? Thanks in advance!

N Strahl
  • 75
  • 8

2 Answers2

4

If you are typing the individual pointer variables out, why not just use a chained assignment?

ptr1 = ptr2 = ptr3 = nullptr;  // All three pointers are nullptr.

DEMO.


[...] or maybe there is already a better alternative to setting all pointers in a container to nullptr.

If you have your pointers in an actual containers as compared to separate, named pointer variables, you can use a range-based for loop to write to and read the pointer elements of the container:

#include <array>
#include <ios>
#include <iostream>

// Container of 'pointer-to-const-int' elements.
using MyPointersArray = std::array<int const*, 3>;

void inspectNullptrness(const MyPointersArray& arr) {
    for (const auto& p : arr) {
        std::cout << std::boolalpha 
            << (p == nullptr) << " ";
    }
}

int main() {
    MyPointersArray pointers{nullptr, nullptr, nullptr};
    const int a = 42;
    inspectNullptrness(pointers); // true true true
    
    // Set pointers.
    for(auto& p : pointers) { p = &a; }
    inspectNullptrness(pointers); // false false false
    
    // Reset pointers.
    for(auto& p : pointers) { p = nullptr; }
    inspectNullptrness(pointers); // true true true
}
dfrib
  • 70,367
  • 12
  • 127
  • 192
2

I would like to get some sort of reference

You're creating a std::initializer_list with that braced init list. Unfortunately, such list always contains copies and you cannot assign to the variables used to initialise it through that list.

You could use reference wrappers:

for (auto ref : { std::ref(ptr1), std::ref(ptr2), std::ref(ptr3) })
    ref.get() = nullptr;

If you used an array of pointers instead of separate variables, then iterating over them would be trivial:

T* ptrs[3];
for (auto& ptr : ptrs})
    ptr = nullptr;
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • In the 1st example, you could alternatively use pointer-to-pointer elements instead, and then you don't have to involve any overhead with `reference_wrapper`, eg: `for (auto item : { &ptr1, &ptr2, &ptr3 }) *item = nullptr;` – Remy Lebeau Oct 09 '20 at 17:03
  • @RemyLebeau What overhead? It's just a class that contains a pointer. – eerorika Oct 09 '20 at 19:31
  • The overhead of making a function call that constructs and returns an object, and all the compiler processing needed to parse the various templates being used by `reference_wrapper` internally. Whereas a raw pointer is, well, a raw pointer. – Remy Lebeau Oct 09 '20 at 20:22
  • @RemyLebeau There is no overhead from function calls that are expanded inline though. – eerorika Oct 09 '20 at 20:49
  • I still feel like it is just overkill in this example. But whatever. Multiple solutions to the same problem. – Remy Lebeau Oct 09 '20 at 20:55
  • 1
    @RemyLebeau That I agree. `ptr1 = ptr2 = ptr3 = nullptr;` suggested by dfri is much better. – eerorika Oct 09 '20 at 20:57
  • This answer helped me the most in the sense that it explained what the actual root of my problem was. However, the answer by @dfri also helped and therefore got an upvote. – N Strahl Oct 20 '20 at 07:55