0

A use of pointers is the ability to iterate and update a collection, for example:

char list[3]{'a', 'b', 'c'};

char *pointer{list};

pointer++;

*pointer = 'd';

std::cout << list[0] << std::endl;
std::cout << list[1] << std::endl;
std::cout << list[2] << std::endl;

Will result in

a
d
c

Great, but raw pointers and C-style arrays are deprecated in modern C++, in favour of smart pointers, like std::unique_ptr and smart containers, like std::vector.

I tried a bit, but with no result, for example:

char list[3]{'a', 'b', 'c'};

std::unique_ptr<char> pointer{std::make_unique<char>(list[0])};

(*pointer)++;

*pointer = 'd';

Will still result in

a
b
c

What am I missing?

And is it a way to use with std::vector?

康桓瑋
  • 33,481
  • 5
  • 40
  • 90
Nullndr
  • 1,624
  • 1
  • 6
  • 24
  • 5
    "Modern" way is not to iterate over pointers at all. But to do a range based for loop over a container containing instances of objects. – Pepijn Kramer Jul 23 '22 at 09:29
  • Have you noticed that you are incrementing the dereferenced value of your pointer, and attempting to set the value using the same dereference? Regardless, there are very few good reasons to pass around pointers to vectors. – OregonTrail Jul 23 '22 at 09:32
  • 1
    `unique_ptr`s are for _owning_ pointers and `std::unique_ptr pointer{std::make_unique(list[0])};` doesn't create a pointer _to_ `list[0]` but allocates memory for a `char` and initializes it with the value of `list[0]` (it's a copy construction) – Ted Lyngmo Jul 23 '22 at 09:33
  • 1
    The purpose of `std::unique_ptr` is to manage a data resource. Therefore it doesn't make sense to use `std::unique_ptr` to manage an element in a list allocated on the stack (and owning the data). – wohlstad Jul 23 '22 at 09:33
  • You're assuming that `unique_ptr` is very similar to a pointer, but it is almost nothing like one. – molbdnilo Jul 23 '22 at 09:37
  • You may be looking for iterators, which define operations that make them look somewhat like pointers, but they’re no longer considered “modern”. https://stackoverflow.com/questions/2395275/how-to-navigate-through-a-vector-using-iterators-c#2395311 With an interator you can `it++` and `*it` if that’s what you like to do. – OregonTrail Jul 23 '22 at 09:42
  • *"Great, but raw pointers and C-style arrays are deprecated in modern C++, in favour of smart pointers, like `std::unique_ptr` and smart containers, like `std::vector`."* You misinterpreted what you've heard. It's doing ***dynamic allocations*** yourself and keeping the result stored in a raw pointer that's considered bad practice in many situations (see RAII). The first code snippet in the question is fine, whether you're evaluating it by pre C++11 standards or C++20 standards (, that is if you've got a valid reason for not using `list[1] = 'd';` instead of doing pointer shenanigans). – fabian Jul 23 '22 at 09:56
  • You're confusing concepts. Pointers *can* be used in several ways (e.g. iterate over a collection, as a handle to access an array), but are easy to misuse. `unique_ptr`s *manage* a pointer (and the object it points at) but are not used to iterate. Standard containers (`std::vector`, etc) manage a collection, and *iterators* are used to iterate over the collection - and a pointer *can* be used or viewed as a primitive/unsafe iterator. "Modern" ways to iterate over a collection use iterators other than pointers OR range-based loops (which use iterators in some specified ways). – Peter Jul 23 '22 at 11:36

2 Answers2

0

Only ever user pointers to single objects. And you can't iterate over single objects. So as Pepijn says the modern way is not to do that at all.

For your case you can just use std::array like so:

std::array list{'a', 'b', 'c');

for (const auto &c : list) { std::cout << c << std::endl; }

For dynamic cases use std::vector or any of the other containers.

Goswin von Brederlow
  • 11,875
  • 2
  • 24
  • 42
0

Loop like this :

// #include <array> for fixed size arrays.
#include <vector> // arrays that can change at runtime, to avoid manually having to write new/delete (or std::make_unique)
#include <string>
#include <iostream>

int main()
{
    std::vector<char> characters{ 'a','b','c' };
    std::vector<std::string> strings{ "Hello", "World" };

    characters.push_back('d'); // add new items to the container

    // use const since loop shouldn't change content
    for (const char character : characters)
    {
        std::cout << character << " ";
    }
    std::cout << "\n";

    // use reference to avoid copy of string in vector to string in loop
    for (const auto& string : strings)
    {
        std::cout << string << " ";
    }
    std::cout << "\n";

    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19