I use the function below to create a list of the leap years between a range of years:
// dynamic initialization
std::vector<int> create_leap_years(const int start_year, const int end_year)
{
std::vector<int> collection;
for (auto year = start_year; year < end_year; year++)
{
const auto is_leap_year = (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
if (is_leap_year)
{
collection.emplace_back(year);
}
}
return collection;
}
I try to learn constexpr and use it to create a static initialization of a list of the leap years for the specified range of years. Should I create a vector and then transform it in a std::array? If I try a function to return an fixed array like below:
// static initialization
static constexpr std::array<int,24>& create_leap_years(const int start_year, const int end_year)
{
// Error: variable in constexpr function does not have automatic storage duration
static const std::array<int, 24> collection =
{ 1904, 1908, 1912, 1916, 1920, 1924, 1928, 1932, 1936,
1940, 1944, 1948, 1952, 1956, 1960, 1964, 1968,
1972, 1976, 1980, 1984, 1988, 1992, 1996 };
return collection;
}
Visual Studio 2019 returns the following error and I am not sure where to go from there:
Error: variable in constexpr function does not have automatic storage duration
Below a complete example of what I try to accomplish:
#include <iostream>
#include <vector>
#include <array>
#if 1
// dynamic initialization
std::vector<int> create_leap_years(const int start_year, const int end_year)
{
std::vector<int> collection;
for (auto year = start_year; year < end_year; year++)
{
const auto is_leap_year = (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
if (is_leap_year)
{
collection.emplace_back(year);
}
}
return collection;
}
#else
// static initialization
static constexpr std::array<int,24>& create_leap_years(const int start_year, const int end_year)
{
// Error: variable in constexpr function does not have automatic storage duration
static const std::array<int, 24> collection =
{ 1904, 1908, 1912, 1916, 1920, 1924, 1928, 1932, 1936,
1940, 1944, 1948, 1952, 1956, 1960, 1964, 1968,
1972, 1976, 1980, 1984, 1988, 1992, 1996 };
return collection;
}
#endif
int main()
{
const auto collection = create_leap_years(1900, 2000);
for (auto year : collection) std::cout << year << " ";
std::cout << std::endl;
return 0;
}
Below the update for the function to return an array based on the feedback I got to return by the array by value:
std::array<int, 100> create_leap_years(const int start_year, const int end_year)
{
static std::array<int, 100> collection{};
auto idx = 0;
for (auto year = start_year; idx < 100 && year < end_year; year++)
{
const auto is_leap_year = (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
if (is_leap_year)
{
collection[idx++] = year;
}
}
return collection;
}