2016-04-12 2 views
2

私は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 */ 
    } 

私は(例えばhereが示唆したように)istringstream`を使用することができます。

std::istringstream iss(*i); 
T t; iss >> t; 
vec.push_back(t); 

しかし、それはやり過ぎだ(と私はここに二回、あるいは3回を構築することがあります)。 C++はそのstd::to_stringようstd::from_string()を持っていた場合、私はちょうど

vec.emplace_back(std::from_string(*i)); 

を行うだろうが、それは存在しません。おそらくboost::lexical_cast?私はむしろ何か標準を使用しています。

代わりにどうすればよいですか?

+1

何かを作成するための唯一の「一般的な」方法: 、すべてのTタイプにinstansiationを防ぐdiferent機能でストリームをカプセル化するためには、 はstd::istringstreamを構築するヘルパー関数は、一度すべてのスレッドを形成します'from_string'関数のように*は文字列ストリームであり、実際に' boost :: lexical_cast'がどのように働くのですか?もちろん、適切な 'operator >>'オーバーロードを持つ型( 'T'それが何であれ)に頼っています。数字のようなものを専門に扱うかもしれません。 'strtod'または' stoi'が使われます)が、 'istringstream'のクラッチを逃れる方法はありません。 –

+0

'from_string'関数が存在していても、私はそれを改善する性能/スペースを大いに見ていません。単なる2〜3nの余分な演算であり、全体としてO(n)となる。コードをきれいにすると、自分のテンプレート 'from_string'から' sstream'までカプセル化できます。 – aybassiouny

+0

@aybassiouny:1. from_stringを意味します。 2. istringstreamは、おそらく何らかの構造を必要とします。3. istringstreamは、自分自身の覗き見、トークン化、次の未使用位置の維持などを行いますが、私の場合は文字列全体に1つの値しかありません。私はそれにいくつかのパフォーマンス上の利点があると確信しています。 – einpoklum

答えて

0

アプリケーションがモノスレッドであれば、あなたが関数にストリーム静的に保つ含まないthread_local

他のソリューションは、ストリームをラップすることです破棄することができstatic thread_local

T parse (const string& line){ 
    static thread_local istringstream stream; 
    stream.str(""); //flush the stream 
    //keep using stream 
} 

istringstreamを作ります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"); 
と内部バッファのフラッシュし、そのオブジェクトを使用し続けます

EDIT:

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 

} 
+0

あなたはアバターのために持っているDangerous Dave画像ですか? – einpoklum

+0

私はデイブです。私は危険です:) –

+0

あなたのテンプレート化された解析関数は、私にTのすべての値に対して別個のistreamオブジェクトを与えます。それほど良いことではありません...静的なthread_local変数を保持する、テンプレート化されていないistringstream getter関数についてはどうですか?また、thread_local C++ 11ですか? C++ 14? C++ 17? – einpoklum

関連する問題