[英]Parameter pack, capture clause and initializers
注意 :這個問題是出於好奇。
以下代碼是合法的:
template<typename... T>
void f(T... t) {
auto lambda = [t...](){ /* do something */ };
// do something else
}
對於這一點同樣不用說:
void f(int i) {
auto lambda = [i = i](){ /* do something */ };
// do something else
}
我想知道是否有可能在參數包的capture子句中定義一個初始化程序。
像這樣:
template<typename... Args>
void f(Args&&... args) {
auto lambda = [params = std::forward<Args>(args)...](){ /* do something */ };
// do something else
}
好的,我懷疑這沒有意義,但至少可以提供一個想法。
有可行的解決方案嗎?
拜托,不要問我為什么要這么做。 我不想那樣做。 正如我所說,這是出於好奇。
不。
最好的辦法是:
template<typename... Args>
void f(Args&&... args) {
auto lambda = [params = std::make_tuple(std::forward<Args>(args)...)]()
{ /* do something */ };
// do something else
}
然后與params
作為tuple
進行交互,包括使用get
。
我發現您最終不得不離開lambda的世界來再次解壓縮元素。 大概可以用這樣的助手來做到這一點:
template<std::size_t...Is, class F>
decltype(auto) unpack_impl( std::index_sequence<Is...>, F&& f ) {
return std::forward<F>(f)(std::integral_constant<std::size_t, Is>{}...);
}
template<std::size_t N, class F>
decltype(auto) unpack( F&& f ) {
return unpack_impl( std::make_index_sequence<N>{}, std::forward<F>(f) );
}
它接受一個模板非類型參數N
,然后生成一個帶有constexpr operator size_t
且值從0
到N-1
的integral_constants
_ constexpr operator size_t
包,並將其傳遞給您通過unpack
傳遞的lambda。
使用示例:
template<typename... Args>
auto print_later(Args&&... args) {
auto lambda = [params = std::make_tuple(std::forward<Args>(args)...)](
auto&& stream
)
{
unpack<sizeof...(Args)>( [&](auto...Is){
using discard=int[];
(void)discard{0,(void(
stream << std::get<Is>( params )
),0)...
};
});
};
return lambda;
}
注意Is
傳遞到內部拉姆達。 基本上,這種技術使我們可以解壓縮參數包並在可擴展的上下文中獲取其值,而無需創建新的顯式模板函數。 相反,我們創建一個可變參數的lambda,並使用參數的類型(或對其進行constexpr操作)來獲取解壓縮結果。
上面的函數接受一攬子參數,並返回接受流並打印所有參數的函數。
unpack
功能可以變得更加通用。 至少要讓它采用integer_sequence
,最后甚至是一個變體都可以直接采用一堆類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.