是否可以在不指定类型的情况下从 istringstream 转到向量?
Is it possible to go from istringstream to a vector without specifying the type?
这个有效:
std::istringstream("1234") >> mystruct.member;
但是,如果我想 push_back()
将值转换为未知类型的向量怎么办?
部分解决方案:
decltype(some_vector)::value_type buf;
istringstream("1234") >> buf;
some_vector.push_back(buf);
是否可以在没有缓冲区变量的情况下执行此操作?
如果您的字符串流保证包含 space 分隔的元素并与您的容器类型相对应,那么您可以这样做
template <typename Container>
void get_input(std::istream& is, Container& container) {
auto val = typename std::decay_t<Container>::value_type{};
while (is >> val) {
container.push_back(std::move(val));
}
}
请注意,我没有使用模板模板参数来推断容器模板化的类型,因为使用 value_type
提供了与容器的更强大的合同。
A partial solution to it:
decltype(some_vector)::value_type buf;
istringstream("1234") >> buf;
some_vector.push_back(buf);
Is it possible to do this without a buffer variable?
是的,在下面的程序中它是在没有缓冲区的情况下完成的,但这是有代价的。
在下面的程序中,创建了一个迭代器,它将提取所需的值并将它们放入向量中。它这样做并没有公开创建缓冲区变量。它适用于不同类型的向量。
#include <sstream>
#include <vector>
#include <string>
#include <iostream>
#include <iterator>
struct done_reading {};
template<typename T, typename charT>
T extract(std::basic_istream<charT>& is) {
std::istream_iterator<T> it{is};
if(it != decltype(it){}) {
return *it;
}
throw done_reading{};
}
struct mystruct { int member{}; };
template<typename charT>
std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, mystruct& m) { is >> m.member; return is; }
std::ostream& operator<<(std::ostream& os, mystruct& m) { os << m.member; return os; }
template <typename T, typename S>
S& operator>>(S&& is, std::vector<T>& some_vector)
{
for(;;)
try {
some_vector.emplace_back(extract<T>(is));
}
catch(done_reading)
{
return is;
};
}
template<typename T>
void make_and_print()
{
std::vector<T> some_vector;
std::istringstream{"1234 5678 9101112"} >> some_vector;
std::istringstream iss{"43728 754382 69548"};
iss >> some_vector;
for(auto&& i : some_vector)
std::cout << i << '\n';
}
int main()
{
make_and_print<int>();
make_and_print<mystruct>();
}
这个有效:
std::istringstream("1234") >> mystruct.member;
但是,如果我想 push_back()
将值转换为未知类型的向量怎么办?
部分解决方案:
decltype(some_vector)::value_type buf;
istringstream("1234") >> buf;
some_vector.push_back(buf);
是否可以在没有缓冲区变量的情况下执行此操作?
如果您的字符串流保证包含 space 分隔的元素并与您的容器类型相对应,那么您可以这样做
template <typename Container>
void get_input(std::istream& is, Container& container) {
auto val = typename std::decay_t<Container>::value_type{};
while (is >> val) {
container.push_back(std::move(val));
}
}
请注意,我没有使用模板模板参数来推断容器模板化的类型,因为使用 value_type
提供了与容器的更强大的合同。
A partial solution to it:
decltype(some_vector)::value_type buf; istringstream("1234") >> buf; some_vector.push_back(buf);
Is it possible to do this without a buffer variable?
是的,在下面的程序中它是在没有缓冲区的情况下完成的,但这是有代价的。
在下面的程序中,创建了一个迭代器,它将提取所需的值并将它们放入向量中。它这样做并没有公开创建缓冲区变量。它适用于不同类型的向量。
#include <sstream>
#include <vector>
#include <string>
#include <iostream>
#include <iterator>
struct done_reading {};
template<typename T, typename charT>
T extract(std::basic_istream<charT>& is) {
std::istream_iterator<T> it{is};
if(it != decltype(it){}) {
return *it;
}
throw done_reading{};
}
struct mystruct { int member{}; };
template<typename charT>
std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, mystruct& m) { is >> m.member; return is; }
std::ostream& operator<<(std::ostream& os, mystruct& m) { os << m.member; return os; }
template <typename T, typename S>
S& operator>>(S&& is, std::vector<T>& some_vector)
{
for(;;)
try {
some_vector.emplace_back(extract<T>(is));
}
catch(done_reading)
{
return is;
};
}
template<typename T>
void make_and_print()
{
std::vector<T> some_vector;
std::istringstream{"1234 5678 9101112"} >> some_vector;
std::istringstream iss{"43728 754382 69548"};
iss >> some_vector;
for(auto&& i : some_vector)
std::cout << i << '\n';
}
int main()
{
make_and_print<int>();
make_and_print<mystruct>();
}