2016-09-19 6 views
10

私はstd::string_viewを使用する動機を理解しています。
これは、関数の引数に不要な割り当てを避けるのに役立ちます。例えばstd :: string_viewの代わりにconst&std :: stringを渡すのはいつですか?


次のプログラムは、文字列リテラルからstd::stringを作成します。
これは望ましくない動的割り当てを引き起こします。これは、文字を観察することだけに興味があるからです。

#include <iostream> 

void* operator new(std::size_t n) 
{ 
    std::cout << "[allocating " << n << " bytes]\n"; 
    return malloc(n); 
} 

void observe_string(std::string const& str){} 

int main(){ 
    observe_string("hello world"); //prints [allocating 36 bytes] 
} 

string_viewを使用することで問題を解決します:

#include <iostream> 
#include <experimental/string_view> 

void* operator new(std::size_t n) 
{ 
    std::cout << "[allocating " << n << " bytes]\n"; 
    return malloc(n); 
} 

void observe_string(std::experimental::string_view const& str){ 
} 

int main(){ 
    observe_string("hello world"); //prints nothing 
} 

これは質問を私に残します。
関数引数にstring_viewの代わりにconst &でstd :: stringを選択するのはいつですか?私はconst&によって渡されstd::stringのすべてのインスタンスを置き換えることができているかのよう

std::string_viewのインタフェースを見ると、それが見えます。これに反例がありますか? std::string_viewはパラメータを渡すためにstd::string const&を置き換えることを意味していますか?

+0

私は、関数がパラメータを離散的なstd :: stringに内部的に隠すつもりならば、コピー構築は文字列から文字列へのビューから文字列へのラウンドトリップよりも安いでしょう。しかし、basic_string_viewはそれが文字列から構築されたことを記憶し、同じto_string()メソッドから同じものを返すことに気付きました。 –

+0

@SamVarshavchik:もしあなたがコピーを作ろうとするなら、あなたは引数で値を受け入れて、それをコピーまたは移動構築することができます。 – GManNickG

答えて

2

Andrei Alexandrescuが一度言った、"いいえ仕事はいくつかの仕事より良いです"。したがって、このような状況ではconst std::string&を使用する必要があります。 std::string_viewにはまだいくつかの作業(ポインタと長さのペアのコピー)が必要なためです。

もちろん、const参照にはまだポインタをコピーするコストがかかります。これはほぼstd::string_viewと同じです。しかし、std::string_viewの追加作業が1つあります。長さもコピーされます。

これは理論的にはあるが、実際には、ベンチマークのパフォーマンスを推測することが好ましい


+0

@ M.M各回帰において同じスライスを見ていないと仮定しますか? – WhiZTiM

+0

@ M.M、私は再帰の例を削除しました。実際にはOPの質問ではないstring_viewを使用しています。 – WhiZTiM

+4

関数が文字列リテラルで呼び出された場合、 'const string&'バージョンはより多くの作業を行います。 – juanchopanza

5

私はconst&の代わりに、関数の引数のためのstring_viewstd::stringを選ぶだろういつですか?

null終了文字列?もしそうなら、その保証を与えるstd::string const&を使うべきです。 string_viewはありません - それは単にconst charの範囲です。

にヌルで終了する文字列が必要でないため、データの所有権を取得する必要がない場合は、string_viewを使用してください。データの所有権を取得する必要がある場合は、値によってstringstring_viewより優れている場合があります。

+2

説明のために:私の文字列がnullで終わることを必要とするということは、 'std :: string'の' char'配列が '\ 0'で終わるべきであることを意味します。誰かが 'std :: string'をすでに使っている時にこれが必要であると想像するのは難しいです。そのようなCと現代のC++を混在させるようなものか、間違っていますか? –

+0

NTBSが必要な人は、 'const char *'をパラメータ型として使うことができると思います。 – cpplearner

+0

@ M.Winter想像するのは簡単です...ヌルターミネーション文字列を必要とするAPIがたくさんあります。 – Barry

2

const std::string&の代わりにstring_viewを受け入れる理由の1つは、後で変更できる文字列オブジェクトへの参照を保存する場合です。

string_viewを受け入れて保存する場合は、string内部バッファを再割り当てすると無効になることがあります。

文字列自体への参照を受け入れて保存すると、そのオブジェクトが存続している限り、その問題は発生しません(おそらく一時的な問題を避けるためにr値参照のオーバーロードを削除することをお勧めします)。

関連する問題