[英]How to avoid repeated istringstream construction when converting stream of string tokens
我(打算)使用此答案中的代碼從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`(例如在這里建議):
std::istringstream iss(*i);
T t; iss >> t;
vec.push_back(t);
但這太過分了(我可能在這里構造了兩次甚至三遍)。 如果C ++像其std::to_string
一樣有一個std::from_string()
,那么我會做
vec.emplace_back(std::from_string(*i));
但這不存在。 也許boost::lexical_cast
? 我真的很想使用標准的東西。
我該怎么辦呢?
使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
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.