使用C++ 1z,它非常簡單,用fold expressions。首先,元組轉發到_impl
函數並提供它與索引序列來訪問所有元組的元素,然後總和:
template<typename T, size_t... Is>
auto sum_components_impl(T const& t, std::index_sequence<Is...>)
{
return (std::get<Is>(t) + ...);
}
template <class Tuple>
int sum_components(const Tuple& t)
{
constexpr auto size = std::tuple_size<Tuple>{};
return sum_components_impl(t, std::make_index_sequence<size>{});
}
demo
A C++ 14的方法是遞歸地總結一個可變參數包:
int sum()
{
return 0;
}
template<typename T, typename... Us>
auto sum(T&& t, Us&&... us)
{
return std::forward<T>(t) + sum(std::forward<Us>(us)...);
}
template<typename T, size_t... Is>
auto sum_components_impl(T const& t, std::index_sequence<Is...>)
{
return sum(std::get<Is>(t)...);
}
template <class Tuple>
int sum_components(const Tuple& t)
{
constexpr auto size = std::tuple_size<Tuple>{};
return sum_components_impl(t, std::make_index_sequence<size>{});
}
demo
C++ 11方法將是定製實現index_sequence
的C++ 14方法。例如從here。
由於@ildjarn在評論中指出,上述例子都採用正確的褶皺,而許多程序員希望在他們的代碼左倍。 C++的1Z版本是平凡多變:
template<typename T, size_t... Is>
auto sum_components_impl(T const& t, std::index_sequence<Is...>)
{
return (... + std::get<Is>(t));
}
demo
而C++ 14不是差很多,但也有更多的變化:
template<typename T, typename... Us>
auto sum(T&& t, Us&&... us)
{
return sum(std::forward<Us>(us)...) + std::forward<T>(t);
}
template<typename T, size_t... Is>
auto sum_components_impl(T const& t, std::index_sequence<Is...>)
{
constexpr auto last_index = sizeof...(Is) - 1;
return sum(std::get<last_index - Is>(t)...);
}
demo
只需要一些'decltype(auto)'噴灑。 –
@ T.C。加入口味。最初忽略它們是因爲我不想考慮表達式模板和其他混亂。從臨時自動存儲對象的字段中返回的中間結果「T &&」可能會與上述情況相沖突。但現在我認爲這是表達模板的問題。 – Yakk
非常感謝。這個解決方案甚至比@ krzaq更好,因爲你使用了我以前不知道的std :: apply。我接受你的解決方案。 – Max