其他分享
首页 > 其他分享> > 从c中的字符串向量创建元组

从c中的字符串向量创建元组

作者:互联网

我有一个字符串向量,每个字符串都是将std :: to_string应用于某些基本数据类型(例如char,int,double)的结果.我想要一个函数来将其撤消为适当类型的元组.

我有一个简单的函数模板来反转std :: to_string:

template<typename T>
T from_string(std::string s)
{
}

template<>
int from_string<int>(std::string s)
{
    return std::stoi(s);
}

template<>
double from_string<double>(std::string s)
{
    return std::stod(s);
}

//... and more such specializations for the other basic types

我想要一个像这样的功能:

template<typename... Ts>
std::tuple<Ts> undo(const std::vector<std::string>>& vec_of_str)
{
    // somehow call the appropriate specializations of from_string to the elements of vector_of_str and pack the results in a tuple. then return the tuple.     
}

该函数应该像这样:

int main()
{
    auto ss = std::vector<std::string>>({"4", "0.5"});
    auto tuple1 = undo<int, double>(ss);
    std::tuple<int, double> tuple2(4, 0.5);

    // tuple1 and tuple2 should be identical. 
}

我认为我必须“迭代”Ts中的参数(也许正确的术语是“unpack”),调用前一个函数,from_string为每个函数,然后将from_string的每个应用程序的结果打包成一个元组.我已经看过(并使用过)解压缩模板参数包的示例 – 它们通常是递归的(但不是通常调用函数的方式),但我不知道如何做其余的事情.

解决方法:

一个例子:

#include <vector>
#include <string>
#include <tuple>
#include <cassert>

#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string/trim.hpp>

template<class... Ts, size_t... Idxs>
std::tuple<Ts...>
parse(std::vector<std::string> const& values, std::index_sequence<Idxs...>) {
    return {boost::lexical_cast<Ts>(boost::algorithm::trim_copy(values[Idxs]))...};
}

template<class... Ts>
std::tuple<Ts...> undo(std::vector<std::string> const& values) {
    assert(sizeof...(Ts) == values.size());
    return parse<Ts...>(values, std::make_index_sequence<sizeof...(Ts)>{});
}

int main() {
    auto ss = std::vector<std::string>({"4", "0.5"});
    auto tuple1 = undo<int, double>(ss);
    std::tuple<int, double> tuple2(4, 0.5);
    std::cout << (tuple1 == tuple2) << '\n';
    assert(tuple1 == tuple2);
}

如果字符串值不包含前导和/或尾随空格,则可以删除对boost :: algorithm :: trim_copy的调用.它就在那里因为boost :: lexical_cast在空格上失败了.

如果没有boost :: lexical_cast,你需要重新实现它,例如:

template<class T> T from_string(std::string const& s);
template<> int      from_string<int>(std::string const& s)    { return std::stoi(s); }
template<> double   from_string<double>(std::string const& s) { return std::stod(s); }
// And so on.

template<class... Ts, size_t... Idxs>
std::tuple<Ts...>
parse(std::vector<std::string> const& values, std::index_sequence<Idxs...>) {
    return {from_string<Ts>(values[Idxs])...};
}

标签:variadic,c,templates,variadic-templates,variadic-functions
来源: https://codeday.me/bug/20190823/1697409.html