接受元组并返回另一个元组的函数

pre*_*eys 0 c++ overloading tuples function c++14

如何编写一个函数重载,它接受任意大小的元组并返回另一个相同大小的元组,其中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>.

Ric*_*ges 7

这是一种方式:

第1步 - 声明转换器的概念:

template<class From>
struct converter;
Run Code Online (Sandbox Code Playgroud)

第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;
    }
};
Run Code Online (Sandbox Code Playgroud)

第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)))...);
}
Run Code Online (Sandbox Code Playgroud)

第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>());
}
Run Code Online (Sandbox Code Playgroud)

第5步 - 写一个测试:

int main()
{
    auto t = convert(std::make_tuple(int(1), char('a'), std::size_t(6)));   
}
Run Code Online (Sandbox Code Playgroud)

此解决方案还具有完美的转发功能作为奖励.