Why does std::array not have an constructor that takes a value for the array to be filled with?
std::array
is, by design, an aggregate, so has no user-declared constructors.
As you say, you could use fill
after default constructing. Since it's an aggregate, default construction won't zero the memory, but will leave it uninitialised (if the contained type is trivially initialisable).
How can I initialize an std::array of a class without a default constructor?
With copy constructor, something along these lines:
template <typename T, size_t... Is>
std::array<T, sizeof...(Is)> MakeArrayHelper(
const T& val, std::index_sequence<Is...>) {
return {(static_cast<void>(Is), val) ...};
}
template <typename T, size_t N>
std::array<T, N> MakeArray(const T& val) {
return MakeArrayHelper<T>(val, std::make_index_sequence<N>{});
}
std::array<Foo, 100> arr = MakeArray<Foo, 100>(Foo(5));
Actually, this can be done without copy constructor after all. This solution relies heavily on C++17's mandatory copy elision.
template <typename T, size_t... Is, typename... Args>
std::array<T, sizeof...(Is)> MakeArrayHelper(
std::index_sequence<Is...>, Args&&... args) {
return {(static_cast<void>(Is), T{std::forward<Args>(args)...}) ...};
}
template <typename T, size_t N, typename... Args>
std::array<T, N> MakeArray(Args&&... args) {
return MakeArrayHelper<T>(std::make_index_sequence<N>{},
std::forward<Args>(args)...);
}
Demo
Build initializer list for array by repeating n times
If you want to use a std::array
you are going to need to build a helper function, namely a delegating constructor. Your default constructor will then call the delegate to actually initialize the member. That can look like
class MyClass {
public:
// default c'tor, create sequence of 10 integers
MyClass() : MyClass(std::make_index_sequence<10>{})
private:
// delegate, take a sequence and expand the initializer of myArray sizeof...(Is) times
template <std::size_t... Is>
MyClass(std::index_sequence<Is...>) :
myArray{ (Is, MyComplexType(func(const_arg1, const_arg2, const_arg3).method(const_arg4)))... } {}
std::array<MyComplexType, 10> myArray;
}
You can instead change myArray
to be a vector
instead and that would let you simplify the code to
class MyClass {
public:
MyClass() :
myData(MyComplexType(func(const_arg1, const_arg2, const_arg3).method(const_arg4)), 10) {}
private:
std::vector<MyComplexType> myData;
}
Declare static array in class with size passed to constructor?
Yes, this code
class_name(int n, const int d)
{
float arr[d];
map = arr;
}
is a bad idea, for 2 reasons
float arr[d];
creates a local variable in stack, so it ceases to exist at the end of the block. Somap
becomes a dangling pointer. If you needed dynamic size allocation, you should just usestd::vector<float> map
and avoid a lot of hassle.float arr[d];
is a variable length array, and C++ does not support those. Makingd
beconst
does not help, it has to be an actual constant, notconst
variable.
Solution: Since you say the array length can be determined at compile time, this is perfect fit for a template:
template <std::size_t N>
class class_name
{
public:
std::array<float, N> map { {} }; // { {} } causes value initialization of everything to 0
// actually above could be `float map[N];` but it has the C array gotchas
class_name(int n)
{
// not sure what n is for...
}
};
And to declare a variable of this class:
class_name<5> obj; // obj.map size is 5
How to initialize std::array member in constructor initialization list when the size of the array is a template parameter
std::index_sequence
was provided in order to simplify the metaprogramming task of creating and expanding a pack whose size is not fixed. Use std::make_index_sequence
and delegate the construction to some private constructor that deduces the pack:
A(H h) : A(h, std::make_index_sequence<N>{}) {}
template <std::size_t... i>
A(H h, std::index_sequence<i...>) : hashes{((void)i, h)...} {}
Here, ((void)i, h)
is a comma expression that evaluates to h
, but since we mentioned the pack i
inside it, it's eligible to be expanded using ...
. The result is N
copies of h
(one for each element of i
). This expansion occurs inside a braced-init-list, so the result is a braced-init-list contaning N
copies of h
, which will then initialize the hashes
member.
Initialize an std::array of objects with non-trivial constructor
You might write helper class:
template <std::size_t ... Is, typename T>
std::array<T, sizeof...(Is)> make_array_impl(const T& def, std::index_sequence<Is...>)
{
return {{(Is, void(), def)...}};
}
template <std::size_t N, typename T>
std::array<T, N> make_array(const T& def)
{
return make_array_impl(def, std::make_index_sequence<N>());
}
and then
Cube(int size) : c_edgelets(make_array<12>(Edgelet(size - 2)) {}
Initializing a std::array with a constant value
With std::index_sequence
, you might do:
namespace detail
{
template <typename T, std::size_t ... Is>
constexpr std::array<T, sizeof...(Is)>
create_array(T value, std::index_sequence<Is...>)
{
// cast Is to void to remove the warning: unused value
return {{(static_cast<void>(Is), value)...}};
}
}
template <std::size_t N, typename T>
constexpr std::array<T, N> create_array(const T& value)
{
return detail::create_array(value, std::make_index_sequence<N>());
}
With usage
auto a = create_array<10 /*, int*/>(7); // auto is std::array<int, 10>
Which, contrary to std::fill
solution, handle non default constructible types.
Related Topics
C++ Function to Count All the Words in a String
Winapi Sleep() Function Call Sleeps for Longer Than Expected
When and How to Use Exception Handling
Relative Performance of Std::Vector VS. Std::List VS. Std::Slist
Why/When Is _Declspec( Dllimport ) Not Needed
Number of Combinations (N Choose R) in C++
Is the Pointer Guaranteed to Preserve Its Value After 'Delete' in C++
Are Vectors Passed to Functions by Value or by Reference in C++
Simple Way to Unzip a .Zip File Using Zlib
Precise Thread Sleep Needed. Max 1Ms Error
Why Does Std::Array Not Have an Constructor That Takes a Value for the Array to Be Filled With
Variadic Function Template with Pack Expansion Not in Last Parameter
How to Use Std::String in a Constexpr
C++ Equivalent to Java's Blockingqueue
Difference in Performance Between Msvc and Gcc for Highly Optimized Matrix Multplication Code
Matching Alias Template as Template Argument
Differencebetween Const_Iterator and Non-Const Iterator in the C++ Stl