用一个值(可能有也可能没有不同的类型)替换元组的第 n 个元素的最短/最佳方法是什么?包括 c++20 在内的解决方案很好。[编辑:我更喜欢不需要其他库的东西,但我仍然对使用例如 boost 可能的解决方案感兴趣]。
IE:
#include <cassert>
#include <tuple>
template<std::size_t N, ... >
auto replace_tuple_element( ... ) // <- Looking for a suitable implementation
struct Foo {
int value;
};
int main()
{
auto t1 = std::tuple{ 0, 1, 2, 3 };
auto t2 = replace_tuple_element<2>( t1, Foo{10} );
assert( std::get<0>(t2) == std::get<0>(t1));
assert( std::get<1>(t2) == std::get<1>(t1));
assert( std::get<2>(t2).value == 10);
assert( std::get<3>(t2) == std::get<3>(t1));
}
Run Code Online (Sandbox Code Playgroud)
注意:仅替换类型列表中的第 n 个类型已经在这里讨论过:如何在编译时替换元组元素?. 但我也想替换这个值,并希望现在在 c++20 中有比问这个问题时更简单/更优雅的解决方案。
我为 c++20 找到的一种解决方案是:
#include <cassert>
#include <tuple>
#include <type_traits>
template<std::size_t N, class TupleT, class NewT>
constexpr auto replace_tuple_element( const TupleT& t, const NewT& n )
{
constexpr auto tail_size = std::tuple_size<TupleT>::value - N - 1;
return [&]<std::size_t... I_head, std::size_t... I_tail>
( std::index_sequence<I_head...>, std::index_sequence<I_tail...> )
{
return std::tuple{
std::get<I_head>( t )...,
n,
std::get<I_tail + N + 1>( t )...
};
}(
std::make_index_sequence<N>{},
std::make_index_sequence<tail_size>{}
);
}
struct Foo {
int value;
};
int main()
{
auto t1 = std::tuple{ 0, 1, 2, 3 };
auto t2 = replace_tuple_element<2>( t1, Foo{10} );
assert( std::get<0>(t2) == std::get<0>(t1));
assert( std::get<1>(t2) == std::get<1>(t1));
assert( std::get<2>(t2).value == 10);
assert( std::get<3>(t2) == std::get<3>(t1));
}
Run Code Online (Sandbox Code Playgroud)
我喜欢这个解决方案的地方在于它是一个单一的、自包含的函数。我想知道是否有更短和/或更易读的东西。
| 归档时间: |
|
| 查看次数: |
195 次 |
| 最近记录: |