1

I have a struct with a class member I'd like to make const because it should never be changed after the constructor:

struct S
{
    S(const double pp) : p(pp){}

    const double p;
};

However, I would like to create an std::array of S, of size 1000 (a size too large to explicitly construct each element).

I am aware STL array elements need a default constructor.

Is it possible to define a function called create_array() which can be used like this:

const double p = from_config("p");
std::array<S, 1000> = create_array(p);

and allow me to keep the class member as const?

6
  • Is there a reason you need std::array and not std::vector? Commented Apr 22, 2024 at 3:16
  • I believe this may solve your problem. stackoverflow.com/q/57756557/11638718 Commented Apr 22, 2024 at 3:30
  • @康桓瑋 Would that get around the fact std::array elements require a default constructor but I have a const class member? That question is for an array of integers, not a struct/class. Commented Apr 22, 2024 at 3:51
  • @intrigued_66 See demo as shown here. Commented Apr 22, 2024 at 3:55
  • 2
    Const and reference class members are annoying in general. You should rather make the whole object const, not the individual members. Commented Apr 22, 2024 at 4:00

1 Answer 1

6

Is it possible to define a function called create_array() which can be used like this: std::array<S, 1000> = create_array(p);

Yes, it is possible to do exactly this as shown below:

#include <array>
#include <iostream>

struct S
{
    S(const double pp) : p(pp){}

    const double p;
};

template <typename T, std::size_t ...I>
constexpr auto make_array(std::index_sequence<I...>, double p) {
    return std::array<T, sizeof...(I)>{((I-I), p)...};
}

//version that forwards/passes the args 
template<typename T, std::size_t N>
constexpr auto create_array(double p) {
    return make_array<T>(std::make_index_sequence<N>(), p);
}

int main(void)
{
    const double p = 5.5;
    auto a = create_array<S, 5>(p);
    for(const auto &elem: a)
    {
        std::cout << elem.p << "\n";
    }
    
    return 0;
}

Working demo

The output of the program is:

5.5
5.5
5.5
5.5
5.5
Sign up to request clarification or add additional context in comments.

6 Comments

Here is an expanded version of your demo that adds syntax closer to what the OP is looking for: onlinegdb.com/mffL3eFGE
@RemyLebeau Yes, updated. Btw I was thinking of posting that also as an alternative solution(like method 2) but then decided not to post it for some reason(had to go to the gym actually). Now that you've mentioned it and I'm back, I've updated the answer to that code.
Although this is a possible dupe, I like the tailoring to the OP's problem. Nice. +1.
@wohlstad Yeah, this answer in the dupe should help OP solve their problem as well. Thanks
Hi, only for comments. I try this at VC2022 17.10.3 Community and after 62 size at command <auto a = create_array<S, 1024*63>(p);> VC show erro at run or size like 100000 do`t compile.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.