4

I am trying to achieve something like this

struct A {
    A(const int (&arr)[5])
      :  arr_(arr)
    {}

    const int arr_[5];
}

and obviously this doesn't work. My intent is to keep arr_ field constant. What is the best way to achieve this (can be C++11)?

1
  • 1
    The fundamental problem for why this cannot be done directly is that raw arrays are not copyable, but they become indirectly copyable as member variables of a class. This is essentially why std::array works the way it does. Commented Jun 22, 2016 at 10:27

3 Answers 3

5

Use std::array:

struct A {
    A(std::array<int, 5> const& arr)
      :  arr_(arr)
    {}

    std::array<int, 5> const arr_;
}
Sign up to request clarification or add additional context in comments.

Comments

3

With forwarding constructor:

struct A {
    A(const int (&arr)[5]) : A(arr, std::make_index_sequence<5>()) {}

    const int arr_[5];
private:
    template <std::size_t ... Is>
    A(const int (&arr)[5], std::index_sequence<Is...>)
      : arr_{arr[Is]...}
    {}
};

Comments

1

You might use a std::array internally and convert an array:

#include <array>
#include <utility>

template <typename T, std::size_t ... I>
constexpr std::array<T, sizeof...(I)>
make_sequence(std::integer_sequence<std::size_t, I...>, const T (&array)[sizeof...(I)])  {
    return { array[I] ... };
}

template <typename T, std::size_t N>
constexpr std::array<T, N>
make_sequence(const T (&array)[N]) {
    return make_sequence(std::make_index_sequence<N>(), array);
}


// Test

#include <cassert>
struct A {
    constexpr A(const int (&arr)[5])
      :  arr_(make_sequence(arr))
    {}

    const std::array<int, 5> arr_;
};

int main()
{
    int array[5] = { 0, 1, 2, 3, 4 };
    A a(array);
    assert(a.arr_[2] == 2);
    return 0;
}

However, if you are free to modify the interface of class A, go with the answer of @ecatmur.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.