我如何编写一个函数重载,它接受一个任意大小的元组并返回另一个相同大小的元组,其中 int 变为 double(添加 0.5 值),char 变为 string,size_t 变为 int(通过变为相反的符号),以及我们可能想要的任何其他类型的更改。例如函数 foo
需要 tuple<int, char, size_t>
并返回 tuple<double, string, int>
, 而它需要 tuple<size_t, char>
并返回 tuple<int, string>
.
这是一种方法:
第 1 步 - 声明转换器的概念:
template<class From>
struct converter;
第 2 步 - 定义它的一些特化。这些阐明了转换规则。
template<> struct converter<int>
{
template<class Arg>
auto operator()(Arg&& arg) const {
return std::size_t(arg);
}
};
template<> struct converter<char>
{
template<class Arg>
auto operator()(Arg&& arg) const {
return std::string(1, arg);
}
};
template<> struct converter<std::size_t>
{
template<class Arg>
auto operator()(Arg&& arg) const {
using int_type = long long;
auto result = int_type(arg);
return -result;
}
};
第 3 步 - 根据输入元组、索引序列和输入元组中每个索引处的类型的转换器编写转换函数(这个有点讨厌):
template<class Tuple, std::size_t...Is>
auto convert_impl(Tuple&& t, std::index_sequence<Is...>)
{
using tuple_type = std::decay_t<Tuple>;
return std::make_tuple(converter<std::tuple_element_t<Is, tuple_type>>()(std::get<Is>(std::forward<Tuple>(t)))...);
}
第 4 步 - 提供易于使用的界面:
template<class Tuple>
auto convert(Tuple&& t)
{
using tuple_type = std::decay_t<Tuple>;
return convert_impl(std::forward<Tuple>(t),
std::make_index_sequence<std::tuple_size<tuple_type>::value>());
}
第 5 步 - 编写测试:
int main()
{
auto t = convert(std::make_tuple(int(1), char('a'), std::size_t(6)));
}
此解决方案还具有完美转发功能。
我是一名优秀的程序员,十分优秀!