gpt4 book ai didi

c++ - 将一个元组重新映射到另一个元组

转载 作者:行者123 更新时间:2023-12-05 09:00:36 25 4
gpt4 key购买 nike

我正在尝试在两种类型的 std::tuple 之间进行转换,但我无法正确实现。如果类型相同,我希望它进行映射,但它需要允许重复的类型按原始顺序进行映射。

基本逻辑是:

while has pair<input, output>
if type(input) == type(output)
then do map, next input, next output
else
next input
assert(all outputs mapped)

以映射为例:

Sample Remapping

我对解决方案的“最佳”尝试如下所示:

template <auto> struct value {};
template <auto... Vals> struct value_sequence {};
template <class... Vals> struct placeholder {};

template <auto... As, auto... Bs>
constexpr value_sequence<As..., Bs...> operator+(value_sequence<As...>, value_sequence<Bs...>)
{
return {};
}

template <size_t Idx, size_t... Idxs, size_t OtherIdx, size_t... OtherIdxs, class T, class... Ts, class OtherT, class... OtherTs>
constexpr auto mapper(const std::index_sequence<Idx, Idxs...>&, const std::index_sequence<OtherIdx, OtherIdxs...>&, const placeholder<T, Ts...>&,
const placeholder<OtherT, OtherTs...>&)
{
if constexpr (sizeof...(OtherIdxs) == 0)
{
static_assert(std::is_same_v<T, OtherT>);
return value_sequence<Idx>{};
}
else if constexpr (std::is_same_v<T, OtherT>)
{
return value_sequence<Idx>{} +
mapper(std::index_sequence<Idxs...>{}, std::index_sequence<OtherIdxs...>{}, placeholder<Ts...>{}, placeholder<OtherTs...>{});
}
else
{
return mapper(std::index_sequence<Idx, Idxs...>{}, std::index_sequence<OtherIdxs...>{}, placeholder<T, Ts...>{}, placeholder<OtherTs...>{});
}
}

调用方式:

mapper(std::make_index_sequence<sizeof...(Ts)>{}, std::make_index_sequence<sizeof...(OtherTs)>{},
placeholder<Ts...>{}, placeholder<OtherTs...>{})

这给出了编译器错误 error C2672: 'mapper': no matching overloaded function found pointing to the else if case of the function mapper

我正在使用 c++17,看起来我需要的所有位都在那里,我只是无法以正确的方式组装它们。

非常感谢任何帮助!

最佳答案

这是一个相当简单的递归实现:

// pop_front implementation taken from https://stackoverflow.com/a/39101723/4151599
template <typename Tuple, std::size_t... Is>
auto pop_front_impl(const Tuple& tuple, std::index_sequence<Is...>)
{
return std::make_tuple(std::get<1 + Is>(tuple)...);
}

template <typename Tuple>
auto pop_front(const Tuple& tuple)
{
return pop_front_impl(tuple,
std::make_index_sequence<std::tuple_size<Tuple>::value - 1>());
}

template <typename...>
std::tuple<> map_tuple(std::tuple<>)
{
return {};
}

template <typename FirstOutput, typename... Outputs,
typename FirstInput, typename... Inputs>
std::tuple<FirstOutput, Outputs...>
map_tuple(const std::tuple<FirstInput, Inputs...>& input)
{
if constexpr (std::is_same_v<FirstInput, FirstOutput>) {
return std::tuple_cat(
std::tuple<FirstOutput>(std::get<0>(input)),
map_tuple<Outputs...>(pop_front(input))
);
} else {
return map_tuple<FirstOutput, Outputs...>(pop_front(input));
}
}

简单的调用它

std::tuple<int, double, char, int, int, float> tup = {1, 2.0, '3', 4, 5, 6.0};
auto mapped = map_tuple<int, double, char, float>(tup);

Demo

关于c++ - 将一个元组重新映射到另一个元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75415345/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com