在std :: tuple中转换元素

时间:2017-12-26 14:51:23

标签: c++ tuples

我有一个std::tuple,其中包含字符串,我想将该元组的元素转换为整数。这可能吗?

E.g:

std::tuple<std::string,std::string>("1","2") --> std::tuple<int,std::string>(1,"2")

2 个答案:

答案 0 :(得分:2)

如果要在运行时更改std::tuple容器的某个基础类型,然后,则无法进行更改。如果您只是想将其中一个值转换为int,那么您应该定义另一个元组并使用std::stoi函数:

std::tuple<std::string, std::string> t1("1", "2");
std::tuple<int, std::string> t2(std::stoi(std::get<0>(t1)), std::get<1>(t1));

或使用std::make_tuple函数和auto说明符,让编译器推导出类型:

auto t3 = std::make_tuple(std::stoi(std::get<0>(t1)), std::get<1>(t1));

答案 1 :(得分:0)

这是一个通用的解决方案:

template <std::size_t At, class NewType, class Tuple, std::size_t... Idx>
auto convertAt_impl(Tuple const &orig, std::index_sequence<Idx...>) {
    return std::tuple{
        [&] {
            if constexpr(Idx == At)
                return boost::lexical_cast<NewType>(std::get<Idx>(orig));
            else
                return std::get<Idx>(orig);
        }()...
    };
}

template <std::size_t At, class NewType, class... Ts>
auto convertAt(std::tuple<Ts...> const &orig) {
    return convertAt_impl<At, NewType>(orig, std::index_sequence_for<Ts...>{});
}

它使用boost::lexical_cast来执行转换,但您可以将其替换为您想要的任何转换工具。

可以这样调用:

int main() {
    std::tuple tup{"1", "2"};

    auto tup2 = convertAt<0, int>(tup);

    static_assert(std::is_same_v<decltype(tup2), std::tuple<int, char const *>>);

    std::cout << std::get<0>(tup2) << ' ' << std::get<1>(tup2) << '\n';
}

...将传递断言并打印我们期望的内容。

我会包含一个Coliru演示的链接,但是它的GCC会在包扩展lambda时触发,而它的Clang不知道if constexpr或类模板参数推断是什么。嘿。