簡體   English   中英

轉換字符串令牌流時如何避免重復的istringstream構建

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM