可以用重复的函数调用初始化const std :: array吗?

时间:2017-07-12 05:57:12

标签: c++ arrays c++11

是否可以这样做

int foo(){
  static int i=0;
  ret = i++;
  return ret;
}
const std::array<int,3> arr = {{foo(),foo(),foo()}};

在(模板?)函数中或指定&#34;调用foo来初始化每个成员&#34;?即

const std::array<int,3> arr = fill_with_foo<3,foo>();

对于上下文,arr是队列中的缓冲区,从中读取N个元素(在编译时已知)。目前我正在使用代码生成来创建长格式,并且我有一个函数,它只是简单地分配一个普通数组,用for循环填充它并返回数组,但我想知道是否有可能让缓冲区数组为const。

//编辑:与链接的&#34;重复&#34;不同,我需要

int foo();

在编译时是不确定的,即我认为constexpr是不可能的(正如我所说,它需要从运行时填充的队列中读取)。我主要对删除无用的副本感兴趣

2 个答案:

答案 0 :(得分:4)

Since C++ 14 one might make use of std::index_sequnce (or implement it manually for older versions):

namespace detail
{

template<typename T, std::size_t N, typename F, std::size_t... I>
constexpr std::array<T, N> construct(F&& func, std::index_sequence<I...>)
{
    return { { (static_cast<void>(I), func())... } };
}

template<typename T, std::size_t N, typename F>
constexpr std::array<T, N> construct(F&& func)
{
    return construct<T, N>(std::forward<F>(func), std::make_index_sequence<N>());
}

}

Then you can apply it as follows:

const auto array = detail::construct<T, 3>(foo);

FULL CODE

Also note that constexpr enables constructing std::array even at compile time.

EXAMPLE

答案 1 :(得分:3)

考虑让函数返回std::array。大多数编译器中的NRVO都会忽略该副本。

#include <array>
#include <iostream>

template <typename T, std::size_t N, typename F>
std::array<T, N> fill_array(F const &fn)
{
    std::array<T, N> arr;

    for (auto i = std::begin(arr); i != std::end(arr); ++i) {
        *i = fn();
    }

    return arr;
}

int foo(){
  static int i=0;
  return i++;
}

int main() {
    auto const arr = fill_array<int, 3>(foo);
    for (auto const &i : arr) {
        std::cout << i << '\n';
    }
    return 0;
}

Demo