Reputation:
Say I am declaring a matrix like this--> long long int A[100][100]. Is there any way to assign the value 1 to all its elements at the time of declaring the matrix?
Upvotes: 1
Views: 1076
Reputation: 12759
As shown in Ted Lyngmo's answer, instead of a long long int A[100][100]
we can declare and initialize a std::array<std::array<long long, 100>, 100>
using a constexpr
function.
Since C++20, it's possible to declare a function with a consteval
specifier which
specifies that a function is an immediate function, that is, every call to the function must produce a compile-time constant.
Moreover, the algorithm std::fill_n
has been made constexpr
.
So that we can write the following two function templates:
#include <algorithm>
#include <array>
template <class Type, std::size_t Size>
consteval auto make_1d_array(Type value)
{
std::array<Type, Size> result;
std::fill_n(result.begin(), Size, value);
return result;
}
template <class Type, std::size_t Rows, std::size_t Cols>
consteval auto make_2d_array(Type value)
{
std::array<std::array<Type, Cols>, Rows> result;
std::fill_n( result.begin(), Rows
, make_1d_array<Type, Cols>(value) );
return result;
}
Upvotes: 1
Reputation: 117308
Is there any way to assign the value 1 to all its elements at the time of declaring the matrix?
I interpret that as you want something constexpr
and I'd use std::array
instead of plain arrays since std::array
s are easier to work with.
I've made templates for make_array
that creates a 1 dimensional array and templates for make_2d_array
that creates a 2 dimensional array, using the first set of templates.
The goal of the templates is that if we for example want a 2d array with 2 rows and 3 columns of int
with all int
s initialized with 1
, this should be created:
std::array<std::array<int, 3>, 2> A{{
{1, 1, 1},
{1, 1, 1}
}};
In the code below make_array<int, 3, 1>()
will create the inner arrays, std::array<int, 3>{1, 1, 1}
, and make_2d_array<int, 2, 3, 1>()
will be equivalent to:
std::array<std::array<int, 3>, 2> A{
make_array<int, 3, 1>(), // std::array<int, 3>{1, 1, 1}
make_array<int, 3, 1>() // std::array<int, 3>{1, 1, 1}
};
These are a set of templates that can accomplish that:
#include <array>
#include <type_traits>
#include <utility>
//-------------------------------------------------------------
template <typename T, T init, std::size_t... X>
constexpr std::array<T, sizeof...(X)>
make_array(std::index_sequence<X...>) {
//
// used for folding only then discarded below
// |
return std::array<T, sizeof...(X)>{ ((void)(X), (init))... };
}
template <typename T, std::size_t X, T init = T{}>
constexpr std::array<T, X> make_array() {
return make_array<T, init>(std::make_index_sequence<X>{});
}
//-------------------------------------------------------------
template <typename T, T init, std::size_t X, std::size_t... Y>
constexpr std::array< std::array<T, X>, sizeof...(Y)>
make_2d_array(std::index_sequence<Y...>) {
return std::array< std::array<T, X>, sizeof...(Y)>{
//
// Y used for folding only and discarded
// |
((void)(Y), make_array<T, X, init>())...
};
}
template <typename T, std::size_t Y, std::size_t X, T init = T{}>
constexpr std::array<std::array<T, X>, Y>
make_2d_array() {
return make_2d_array<T, init, X>(std::make_index_sequence<Y>{});
}
It can then be used like this:
constexpr auto A = make_2d_array<int, 2, 3, 1>(); // Y=2, X=3, init value 1
Full demo (click on the Cppinsights link top left in the demo if you'd like to see how the folding unfolds)
Upvotes: 1
Reputation: 75
You can use the fill_n method and initialize array like this:
std::fill_n(&A[0][0], sizeof(A) / sizeof(**A), 1);
Check this for more information about fill_na.
Hope it solves your question.
Upvotes: 1