ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2019-08-23 13:06:21  阅读:231  来源: 互联网

标签:variadic c templates variadic-templates variadic-functions


我有一个字符串向量,每个字符串都是将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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有