簡體   English   中英

是否可以在傳遞給 function 的通用 lambda 中明確指定模板 arguments?

[英]Is it possible to explicitly specify template arguments in a generic lambda passed to a function?

我想在編譯時已知大小的小容器(如 4-8 個元素)上創建編譯時循環。 只創建一個簡單的循環並不難:我可以創建一個重載operator()的模板仿函數F並像下面的代碼一樣調用它

constexpr std::array<T, N> array{/*fill the array*/};

template <std::size_t index> struct F
{
    void operator()()
    {
        std::vector<T> some_container{/*fill it in runtime*/};
        some_container[index + some_offset] += std::get<index>(array); // Use safe array access
    }
};

template <template<std::size_t> typename F, std::size_t... I>
void iterator_implementation(
    const std::index_sequence<I...> /*unused*/)
{
    ((F<I>{}()), ...);
}

template <template<std::size_t> typename F>
void iterator()
{
    iterator_implementation<F>(std::make_index_sequence<array.size()>{});
}

但是,如果我想創建十個這樣的循環並想方便地傳遞一堆引用(閉包),我絕對應該使用 lambda 函數。 為了在 lambda 中使用std::get ,我應該使用通用 lambda。 因此,下面示例中的函子可能會變成

auto f = [&some_container, some_offset]<std::size_t index>()
{
    some_container[index + some_offset] += std::get<index>(array); // Use safe array access
};

我不能簡單地將這個 lambda 傳遞給iterator ,因為如果不指定模板參數就不可能傳遞模板類型的變量,而且我也不能簡單地獲取 lambda 的類型並將其作為F提供以調用F<I>{}重新創建 lambda。如果我使用typename F而不是template<std::size_t> typename F ,我不能調用f<I>因為typename沒有模板參數,所以不能與它們一起使用。

我還可以將std::get<index>(array)index作為普通的 arguments 傳遞給 lambda function 並避免使用模板參數但保存訪問的安全性。 不過,我希望盡可能使用編譯時常量來檢查它是如何工作的。 我相信將編譯時常量數字作為模板參數傳遞可能比數字是我代碼中的普通變量更有助於編譯器優化我的代碼(即使智能編譯器應該“看到”它並優化調用)。 所以,這是一個關於新知識的問題,而不是討論這種方法是否有幫助。

是否可以根據需要在參數包中使用通用 lambda?

PS 盡管有問題標題,但它不是How to pass generic lambda into function的副本,因為在我的問題中模板參數應該明確指定,而在那個問題中可以推導出來。

在泛型 lambda 中, operator()是一個模板,但 lambda 類型不是。

不需要在索引處實例化模板F<I>{}() ,需要在索引處實例化operator() 由於 lambda 有捕獲,因此需要將其作為模板參數傳遞,而不僅僅是類型。

代替:

template <template<std::size_t> typename F, std::size_t... I>
void iterator_implementation(
    const std::index_sequence<I...> /*unused*/)
{
    ((F<I>{}()), ...);
}

和:

template <typename F, std::size_t... I>
void iterator_implementation(F f,
    const std::index_sequence<I...> /*unused*/)
{

    ((f.template operator()<I>()), ...);
}

完整示例: https://godbolt.org/z/rYTP1KTYc

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM