2017-07-12 61 views
3

是否有可能在做這個可能通過重複的函數調用來初始化const std :: array嗎?

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

(模板?)函數或指定「調用了foo的每一個成員的初始化」?即一種方式。

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

對於上下文來說,arr是一個隊列中的一個緩衝區,它將從中讀取N個元素(在編譯時已知)。目前我正在使用代碼生成來創建長格式,並且我有一個函數,它只是簡單地分配一個普通數組,然後用for循環填充它並返回數組,但我想知道是否有可能使緩衝區數組爲const。

//編輯:不像在鏈接的「複製」,我需要

int foo(); 

是在編譯的時候不確定性,即我認爲constexpr是不可能的(正如我所說的,它需要讀取來自在運行時填充的隊列)。我主要對刪除無用副本感興趣

+0

您是否試過使它成爲constexpr? –

+0

@Bob__不能在運行時填充隊列,我想呢? –

回答

4

由於C++ 14一個可以利用的std::index_sequnce(或手動實現它的舊版本):

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>()); 
} 

} 

然後你可以如下應用它:

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

FULL CODE

還要注意,即使在編譯時,constexpr也能夠構建std::array

EXAMPLE

+0

你確定調用非constexpr函數func不會干擾被調用函數的constexpr- ness?在C++ 11中還有'index_sequence'的實現,自從tag以來值得一提。 –

+1

@ W.F。當然,調用非constexpr函數也使得這個解決方案不是太複雜,這就是爲什麼我編寫*「即使在編譯時」*,但不是「總是在編譯時」* :) –

+0

[here](https:// stackoverflow.com/questions/17424477/implementation-c14-make-integer-sequence)你去:) –

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

+0

是的,我認爲C++ 17甚至可以保證複製elision –

+1

@ W.F。僅適用於RVO,不適用於NRVO。 –

+0

這就是我的想法,我只是不確定複製elision –

相關問題