這個問題在這里已經有了答案: 通過索引實作“constexpr for” 1 個答案 11 天前關閉。
有很多方法可以通過 std::tuple 進行迭代。它類似于基于范圍的for回圈。我想做這樣的事情,但是使用元組的索引來訪問各種元組的元素。
例如,我有不同型別的元組,但它們都有相同的自由函式/運算子std::tuple<float, std::complex, vec3, vec4>,我想在兩個或多個這樣的元組之間做一些操作。
我試著寫這樣的東西:
template<typename Lambda, typename... Types, int... Indices>
void TupleIndexElems_Indexed(TTuple<Types...>, Lambda&& Func, TIntegerSequence<int, Indices...>)
{
Func.template operator()<Indices...>();
}
template<typename TupleType, typename Lambda>
void TupleIndexElems(Lambda&& Func)
{
TupleIndexElems_Impl(TupleType{}, Func);
}
template<typename... Types, typename Lambda>
void TupleIndexElems_Impl(TTuple<Types...>, Lambda&& Func)
{
TupleIndexElems_Indexed(TTuple<Types...>{}, Func, TMakeIntegerSequence<int, sizeof...(Types)>{});
}
用法:
FSkyLightSettings& operator =(FSkyLightSettings& Other)
{
auto Tup1 = AsTuple();
auto Tup2 = Other.AsTuple();
using TupType = TTuple<float*, FLinearColor*, FLinearColor*>;
auto AddFunc = [] <typename Tup, int Index> (Tup t1, Tup t2)
{
*t1.template Get<Index>() = (*t1.template Get<Index>()) (*t2.template Get<Index>());
};
TupleIndexElems<TupType>([=]<int... Indices>
{
AddFunc.template operator()<TupType, Indices>(Tup1, Tup2); // How to fold it?
});
return *this;
}
我認為最好的方法是使用可變 lambda 模板,但是當我嘗試呼叫它時,我對無法使用折疊運算式感到困惑。
是否有任何優雅的解決方案(針對各種版本的 C )?
UPD:我也嘗試過使用遞回 lambda,但由于編譯器錯誤 C3536,我不能:
auto PlusVariadic = [=]<int Index, int... Indices>
{
Plus.template operator()<TupType, Index>(Tup1, Tup2); // How to fold it?
if constexpr (Index != 0)
{
PlusVariadic.operator()<Indices...>();
}
};
uj5u.com熱心網友回復:
在 C 20 中,我用來迭代元組的一種方便方法是創建一個constexpr_for函式,該函式呼叫帶有std::integral_constant引數的 lambda 以允許索引,如我的Achieving 'constexpr for' with indexing post 中所述。
#include <utility>
#include <type_traits>
template<size_t Size, typename F>
constexpr void constexpr_for(F&& function) {
auto unfold = [&]<size_t... Ints>(std::index_sequence<Ints...>) {
(std::forward<F>(function)(std::integral_constant<size_t, Ints>{}), ...);
};
unfold(std::make_index_sequence<Size>());
}
示例用法:
#include <tuple>
#include <iostream>
int main() {
auto Tup1 = std::make_tuple(1, 2.0, 3ull, 4u);
auto Tup2 = std::make_tuple(1ull, 2.0f, 3.0, (char)4);
constexpr auto size = std::tuple_size_v<decltype(Tup1)>;
constexpr_for<size>([&](auto i) {
std::get<i>(Tup1) = std::get<i>(Tup2);
std::cout << "tuple<" << i << "> = " << std::get<i>(Tup1) << '\n';
});
}
輸出:
tuple<0> = 2
tuple<1> = 4
tuple<2> = 6
tuple<3> = 8
在godbolt上試試。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/515137.html
