从 c++ 中的字符串向量创建一个元组
Create a tuple from a vector of strings in 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中的参数(也许正确的术语是"解包"(,调用前面的函数,为每个函数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])...};
}
对于 C++11 -- 如果您没有 C++14(Maxim 解决方案需要(,或者如果您想学习实现递归可变参数模板,则很有用:
#include <string>
#include <vector>
#include <tuple>
#include <cassert>
template <std::size_t N, typename T>
struct Undo
{
static void f(T& tuple, const std::vector<std::string>& vec_of_str)
{
Undo<N - 1, T>::f(tuple, vec_of_str);
std::get<N - 1>(tuple) = from_string<
typename std::tuple_element<N - 1, T>::type
>(vec_of_str[N - 1]);
}
};
template <typename T>
struct Undo<0, T>
{
static void f(T&, const std::vector<std::string>&)
{
}
};
template <typename... Ts>
std::tuple<Ts...> undo(const std::vector<std::string>& vec_of_str)
{
assert(vec_of_str.size() == sizeof...(Ts));
std::tuple<Ts...> ret;
Undo<sizeof...(Ts), std::tuple<Ts...>>::f(ret, vec_of_str);
return ret;
}
相关文章:
- 在boost::hana中给定一个键元组,如何从映射中获取值元组
- 从 c++ 中的字符串向量创建一个元组
- 用一个额外的元素扩展 std::array 的每个 std::元组
- 我在代码中收到一个运行时错误,该错误如何通过修改最多一个元素来查找数组是否可以变得不减少
- 使用对另一个元组不同类型的元素的非常量引用来初始化元组的元素
- 您可以static_assert一个元组只有一种满足特定条件的类型
- 使用参数包和元组创建一个简单的表达式类
- 如何将多个可变参数模板元组类组合成一个类?
- 我如何打印一个元组矢量
- 初始化boost :: hana ::元组用一个参数
- 如何创建一个 std::tuple,其中包含由索引元组指定的向量中的成员
- c++存储映射元组的引用,以便在另一个函数中使用
- 接受元组并返回另一个元组的功能
- 通过在上一个数组结束后立即存储下一个元素来扩展数组
- 做一个CPP分类的元组
- 用另一个元组中的元素填充一个元组
- 我正在使用可变参数模板在 C++11 中创建一个元组类。如何使用其实例变量?
- 创建一个元组样式的类来优化未使用的部分
- 如何剥离一个元组<>回到可变类型模板列表
- 段故障返回一个元组