2016-05-25 4 views
0

Предположим, что у меня есть функция обратного вызова, принимающая строковый параметр. Эта функция обратного вызова вызывается с строковым объектом, который больше не нужен на сайте вызова, и, скорее всего, этой функции потребуется выполнить некоторую строчную обработку. Что бы вы посоветовали использовать для параметра - lvalue reference, rvalue reference или const lvalue reference или что-то еще?Передать параметр строки функции обратного вызова в 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)); 

Way 1 кажется быстрым (функция может выполнять обработку строк с исходной строки, избегая копирования или перемещения), но выглядит немного запутанным (люди могут задаться вопросом, если они должны изменить этот параметр).

Путь 3, по-видимому, является наиболее широко используемым способом, но является самым медленным, так как функция должна будет сделать копию переданной строки перед обработкой.

Путь 2, вероятно, посередине.

ОБНОВЛЕНИЕ: На основе ответов добавлен способ 4 (передать по значению + std :: move).

ответ

3

Вы можете принять его по значению и вызвать вызывающего абонента std::move() по аргументу. Таким образом, вызываемый получает свою собственную копию, и вызывающий может решить, копировать или перемещать.

Принимая при помощи значения r-значения или не-const, сохраняется при вызове конструктора перемещения. Другими словами, если вы минимизируете количество выполненных команд, то принимайте строку ссылкой.

+0

Я решил принять значение, как вы предположили (оказалось, что я не могу использовать non-const ref, потому что может быть несколько подписчиков, для которых я должен назвать функцию обратного вызова). Но я смущен частью вашего ответа. Понятно, что принятие not-const ref сохраняет вызов вызывающего конструктора move, но почему вы говорите, что принятие с помощью r-значения сохраняет из вызова конструктора перемещения. Это опечатка или я что-то пропустил? – 4LegsDrivenCat

+0

@ 4LegsDrivenCat Я имел в виду r-значение _reference_. –

+0

Да, но по определению принятие с помощью ссылки rvalue подразумевает, что будет вызываться механизм перемещения. – 4LegsDrivenCat

Смежные вопросы