2016-05-25 15 views
0

文字列パラメータを取るコールバック関数があるとします。 このコールバック関数は、コールサイトでもはや必要とされない文字列オブジェクトで呼び出されます。この関数は、文字列処理を行う必要があります。 パラメータ - 左辺値、右辺値、または左辺値の参照などに使用することをお勧めしますか?C++のコールバック関数に文字列パラメータを渡す11

a。最高のパフォーマンスを達成することに懸念がある場合。

b。コードの明瞭性が心配ならば。

CallbackType callback = processMessage; // declared elsewhere 

std::string message; 

// Way 1: lvalue reference 
using CallbackType = std::function<void(std::string&)>; 
callback(message); 

// Way 2: rvalue reference 
using CallbackType = std::function<void(std::string&&)>; 
callback(std::move(message)); 

// Way 3: const lvalue reference 
using CallbackType = std::function<void(const std::string&)>; 
callback(message); 

// Way 4: lvalue 
using CallbackType = std::function<void(std::string)>; 
callback(std::move(message)); 

ウェイ1は、(関数が任意のコピーを避け、元の文字列と文字列処理を行うか、移動することができます)最速のようですが、(彼らは、このパラメータを変更する必要がある場合には、人々は不思議に思うかもしれません)少し混乱に見えます。

ウェイ3が最も広く使われているようですが、処理の前に渡された文字列のコピーを作成する必要があるため、最も遅くなります。

ウェイ2はおそらくパフォーマンスによって途中です。

UPDATE:回答に基づいて、方法4(値渡し+標準:移動)を追加しました。

答えて

3

これは値で受け入れて、呼び出し元が引数にstd::move()を呼び出させるようにすることができます。この方法では、呼び出し先が独自のコピーを取得し、呼び出し元はコピーするか移動するかを決めることができます。

ただし、r値または非const参照を受け入れると、移動コンストラクタを呼び出すことができなくなります。言い換えれば、実行される命令の数を最小限に抑える場合は、参照によって文字列を受け入れます。

+0

あなたが提案したように、私は値で受け入れることに決めました(コールバック関数を呼び出す必要がある複数のサブスクライバがいる可能性があるため、非const参照は使用できませんでした)。 しかし、私はあなたの答えの一部で混乱しています。非const参照を受け入れると、移動コンストラクタを呼び出すことはできませんが、r値を受け入れることで移動コンストラクタを呼び出すことはできません。それはタイプミスですか、私は何かが欠けていますか? – 4LegsDrivenCat

+0

@ 4LegsDrivenCat私はr値_reference_を意味しました。 –

+0

はい、定義ではrvalue参照を受け入れることによって、moveコンストラクタが呼び出されます。 – 4LegsDrivenCat

関連する問題