我(打算)使用this answer中的代码从CSV中读取内容。基本上我得到连续,
个字符之间的字符串的迭代器;但是我没有将它们放在字符串向量中,而是将这些字符串解析为(任意)类型T的元素,这些元素来自模板参数。所以......
template <typename T>
void foo(const std::string& line)
{
// ....
std::vector<T> vec;
using namespace boost;
tokenizer<escaped_list_separator<char> > tk(
line, escaped_list_separator<char>('\\', ',', '\"'));
for (tokenizer<escaped_list_separator<char> >::iterator i(tk.begin());
i!=tk.end();++i)
{
/* magic goes here */
}
我可以使用istringstream`(例如建议的here):
std::istringstream iss(*i);
T t; iss >> t;
vec.push_back(t);
但这太过分了(我可能会在这里建造两次甚至三次)。如果C ++的std::from_string()
与其std::to_string
类似,那么我只会做
vec.emplace_back(std::from_string(*i));
但这并不存在。也许boost::lexical_cast
?我真的宁愿使用标准的东西。
我该怎么办?
答案 0 :(得分:0)
制作istringstream static thread_local
T parse (const string& line){
static thread_local istringstream stream;
stream.str(""); //flush the stream
//keep using stream
}
如果您的应用程序是单线程的,则可以放弃thread_local
其他不涉及将流静态保存到函数的解决方案是使用Parser
对象包装流,并继续使用该对象,使用str
刷新内部缓冲区
class Parser{
std::stringstream stream;
public:
void parse(const std::string& data){
stream.str("");
// the rest
}
}
Parser parser;
parser.parse("my,data");
parser.parse("other,data");
编辑:
为了防止每个T
类型的实例化,将流封装在不同的函数中,
创建一个辅助函数,构造std::istringstream
一次构成每个线程:
namespace detail {
istringstream& getStream(){
static thread_local istringstream stream;
stream.str("");
return stream;
}
} // namespace detail
template<class T>
void parse(){
auto& stream = detail::getStream();
//do soemthing with stream
}