I'm trying to get the sum of a const int
array as a constexpr
so that I can use sum as the size of another array
constexpr int arr[] = {1, 2, 3};
constexpr int sum1 = std::accumulate(arr, arr + 3, 0); // not OK
int arr1[sum1];
The above does not compile as std::accumulate()
does not return a constexpr
. I end up have a workaround like this
template <size_t N>
constexpr int sum(int const a[])
{
return a[N-1] + sum<N - 1>(a);
}
template <>
constexpr int sum<0>(int const a[])
{
return 0;
}
constexpr int arr[] = {1, 2, 3};
constexpr int sum1 = sum<3>(arr);
int arr1[sum1];
Is there any simpler solution?
#define directives create macro substitution, while constexpr variables are special type of variables. They literally have nothing in common beside the fact that before constexpr (or even const ) variables were available, macros were sometimes used when currently constexpr variable can be used.
A constexpr function is a function that can be invoked within a constant expression. A constexpr function must satisfy the following conditions: It is not virtual. Its return type is a literal type.
The easiest way to check whether a function (e.g., foo ) is constexpr is to assign its return value to a constexpr as below: constexpr auto i = foo(); if the returned value is not constexpr compilation will fail.
Constexpr constructors are permitted for classes that aren't literal types. For example, the default constructor of std::unique_ptr is constexpr, allowing constant initialization.
+1 for the C++14 solutions, but I propose a C++11 solution based on a simple recursive constexpr
function
template <typename T, std::size_t N>
constexpr T aSum (T const (&a)[N], std::size_t i = 0U)
{ return i < N ? (a[i] + aSum(a, i+1U)) : T{}; }
So it's possible to write
constexpr int arr[] {1, 2, 3};
constexpr int sum1 { aSum(arr) };
and sum1
become 6
Since C++14's relaxed constexpr you can do something like this:
#include <iostream>
constexpr int arr[] = {1, 2, 3};
template <size_t Size>
constexpr int sum(const int (&arr)[Size])
{
int ret = 0;
for (int i = 0; i < Size; ++i)
ret += arr[i];
return ret;
}
int main()
{
int arr1[sum(arr)];
std::cout << sizeof(arr1) / sizeof(int);
}
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