I have the following problem:
template< size_t... N_i >
class A
{
// ...
std::array< float, /* product of the unpacked elements of N_i */ > arr;
};
As you can see above, I try to declare an std::array
named arr
as a member of a class A
. Here, I want arr
to have the size product of the unpacked elements of N_i
, e.g., in case of A<2,3,4>
, "arr" should have the size 2*3*4=24
.
Does anyone know how this can be implemented?
In C++17:
std::array < float, (... * N_i)> arr;
In C++14:
// outside the class
template<size_t... Ns>
constexpr size_t product(){
size_t p = 1;
for(auto n : { Ns... }) p *= n;
return p;
}
// then
std::array< float, product<N_i...>()> arr;
In C++11:
template<size_t... N_i>
struct product {
static const size_t value = 1;
};
template<size_t N_1, size_t... N_i>
struct product<N_1, N_i...> {
static const size_t value = N_1 * product<N_i...>::value;
};
std::array< float, product<N_i...>::value> arr;
Alternatively, you can use a recursive constexpr
function.
In C++14 you can do this:
size_t v = 1;
size_t _[] = { (v = v*N_i)... };
As a minimal, working example:
#include<cstddef>
template<std::size_t... I>
constexpr auto f() {
std::size_t v = 1;
std::size_t _[] = { (v = v*I)... };
(void)_; // silent a warning and nothing more
return v;
}
int main() {
static_assert(f<2,3,4>() == 24,"!");
}
Your class can be defined as it follows:
template< size_t... N_i >
class A {
// ...
std::array< float, f<N_i...>()> arr;
};
In C++17 fold-expressions
will simplify it.
This can be done with recursive definition of constexpr function.
And in c++14 using variable template this can have cleaner look :
template <typename ...Ts>
constexpr size_t product()
{
return 1;
}
template <size_t I,size_t... Is>
constexpr size_t product()
{
return I * product<Is...>();
}
template <size_t I, size_t... Is>
constexpr size_t prod = product<I, Is...>();
template< size_t... N_i >
class A
{
std::array< float, prod<N_i...> > arr;
};
You can use this function in your array declaration:
template<typename ...Args>
constexpr int multiply(Args&&... args)
{
return (args * ... );
}
It uses C++17 fold expressions, and can be included like
template< size_t... N_i >
class A
{
// ...
std::array< float, multiply(N_i ...) > arr;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With