1

I have a class variable defined like this:

std::shared_ptr<int[]> variable;

I want to make it store ints from 0 to 10

so that when I call variable[1] it returns 1 and so on.

MIA
  • 41
  • 6
  • No it does not work that way. The array owns the int you can't pass that ownership to a unique_ptr or shared_ptr. What you can do is `std::make_shared>` to make a shared_ptr to a fixed size array. Are you sure you need a shared_ptr though? And not a unique_ptr? – Pepijn Kramer Jan 18 '23 at 16:37
  • 5
    Why not use `std::vector` instead ? – wohlstad Jan 18 '23 at 16:37
  • 2
    `std::make_shared(sizeOfArray);` https://godbolt.org/z/rcnc8K9Ko but use of `std::vector` is more handy. – Marek R Jan 18 '23 at 16:37
  • @PepijnKramer I just want to store value, how can i do that – MIA Jan 18 '23 at 16:38
  • 1
    You describe how you want to solve something, but maybe if you tell us what you want to do we can give some better answers. – Pepijn Kramer Jan 18 '23 at 16:38
  • 4
    If you want to store one value, use an int. If you want to store multiple integers and you now the size of the array at compile time use a `std::array`. If your array can grow during runtime use `std::vector`. Arrays and vectors have move semantics and you can pass them by (const reference) to functions, so you hardly ever need a pointer to them (smart or not) – Pepijn Kramer Jan 18 '23 at 16:40
  • 1
    You probably want [this](https://en.cppreference.com/w/cpp/algorithm/iota) and a std::vector or std::array – drescherjm Jan 18 '23 at 16:54
  • @MIA What your question _"How to initialize a shared_ptr as an array of int in C++"_ answered by any of the answers? – Ted Lyngmo Mar 29 '23 at 18:03

2 Answers2

0

I would use the std::array syntax like this

#include <array>
#include <iostream>
#include <memory>

int main()
{
    // use the std::array syntax it will make the dereferenced smartpointer
    // directly behave like an array. You can use index operator and even
    // use it in range based for loops directly
    auto variables = std::make_shared<std::array<int, 10>>();

    for (std::size_t n = 0ul; n < variables->size(); ++n)
    {
        (*variables)[n] = n;
    }

    for (const int value : *variables)
    {
        std::cout << value << " ";
    }

    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19
  • Why would you prefer `shared_ptr>` over `shared_ptr`? The latter has an `operator[]` defined, so you can use more natural `variables[n]` syntax rather than `(*variables)[n]`. The only downside to the latter would be the lack of a `size()`, though – Remy Lebeau Jan 18 '23 at 18:23
  • Yes arrays and C++, I've never been trully happy with them. There is always "something" ;) (But at least std::array behaves like an object, you pass it around by reference, return it and it has its size with it). I guess shared_ptr doesn't have .begin() and .end() either (for algorithms/range based for). The syntax I usually "cleanup" a bit with something like `auto& values = *variables;` Anyway I didn't know about operator[] on shared_ptr yet so thanks for that feedback. – Pepijn Kramer Jan 18 '23 at 18:36
0

How to initialize a shared_ptr as an array of int in C++

If there are only a limited number of values you'd like in the array, the most practical may be to use new[] with an initializer:

std::shared_ptr<int[]> variable(new int[]{0,1,2,3,4,5,6,7,8,9,10});

If you want to initialize it with a bigger range, you could create a helper that uses an index_sequence and pack expansion:

template<std::size_t N, class T>
std::shared_ptr<T[]> make_shared_iota(T start, T stride) {
    return [&]<std::size_t... Is>(std::index_sequence<Is...>) {
        return std::shared_ptr<T[]>(new T[]{start + stride * T{Is}...});
    }(std::make_index_sequence<N>());
}

// create an array of 20 `int` {3,5,7,...,37,39,41}
auto variable = make_shared_iota<20>(3, 2);

or with a little more freedom, using a functor to provide a formula for calculating the values to initialize the array with:

template<std::size_t N, class Func>
auto make_shared_iota(Func&& func) {
    using type = decltype(func(std::size_t{}));

    return [&]<std::size_t... Is>(std::index_sequence<Is...>) {
        return std::shared_ptr<type[]>(new type[]{std::invoke(func, Is)...});
    }(std::make_index_sequence<N>());
}

// create an array of 20 `int` {3,5,7,...,37,39,41}
auto variable = make_shared_iota<20>([](std::size_t x) {
                    return static_cast<int>(3 + x * 2); });
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108