2016-07-27 11 views
1

Пусть Предположим, что у нас есть функция, которая возвращает сложный объект, как std::string:const auto & для хранения результатов функций, стоит ли это?

std::string find_path(const std::string& filename); 

Стоит ли хранить результат вызова этого метода в const auto&?

void do_sth() { 
    //... 
    const auto& path = find_path(filename); 
    //... 
} 

Такой подход предотвращает копирование/перемещение объекта. Ну это хорошо. Но с другой стороны, было введено auto, чтобы объединить левую часть присваивания. Херб Саттер в своем выступлении от CppCon2014 упоминает о современном стиле C++ слева направо https://www.youtube.com/watch?v=xnqTKD8uD64 (39: 00-45: 00).

В C++ 98 хранение std::string при const ref было прекрасным. Как это происходит на C++ 11?

Update (2016-07-27 2:10 GMT + 0):

К сожалению, мой вопрос был не точен. Я имел в виду стиль кодирования - лучше добавить const & или просто остаться с auto и позволить компилятору делать все, что захочет.

обновленный пример:

unsigned int getTimout() { /* ... */ } 

int getDepth() { /* ... */ } 

std::string find_path(const std::string& filename, 
         unsigned int timeout, 
         int depth) { /* ... */ } 

void open(const std::string& path) { /* ... */ } 

два подхода:

void do_sth() { 
    //... 
    auto timeout = getTimeout(); 
    auto depth = getDepth(); 
    const auto& path = find_path(filename, timeout, depth); 
    open(path) 
    //... 
} 

против

void do_sth() { 
    //... 
    auto timeout = getTimeout(); 
    auto depth = getDepth(); 
    auto path = find_path(filename, timeout, depth); 
    open(path); 
    //... 
} 

вопрос: должны ли мы

  • используйте const auto& для хранения сложных возвратных объектов и auto для примитивов, или
  • auto для всего, чтобы сохранить современный стиль C++, который упоминается в его презентации (ссылка выше).
+1

Никогда не возвращайте (возвращайте значение функции) во временное положение в качестве ссылки. –

+2

Прочитать о NVRO http://stackoverflow.com/questions/6233879/move-or-named-return-value-optimization-nrvo –

+4

@ DieterLücking «C++ намеренно указывает, что привязка временного объекта к ссылке на const на стек продлевает срок службы временного до самого срока службы самой ссылки » https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/ –

ответ

2

В C++ 98 сохранение std :: string при const ref было прекрасным. Как это происходит на C++ 11?

Привязка ссылки const к временному строковому объекту в C++ 11. Он по-прежнему имеет такое же поведение, как и раньше.

Теоретическая стоимость инициализации копии из временного (исключение из которого является преимуществом использования ссылки на константу) была значительно уменьшена в C++ 11, поскольку перемещение строки намного дешевле, чем копирование.

Практические затраты на инициализацию копий не изменились с оптимизацией компиляторов, так как они могут в любом случае ускользнуть от копирования/перемещения, поэтому нет затрат - хотя, возможно, зависит от того, как реализовано find_path.


Если вы абсолютно хотите, чтобы избежать копирования/перемещения возвращенную строку и не может взять копию Пропуска, то вы должны создать объект за пределами функции, и передать его в функцию по ссылке.Недостаточно привязки ссылки к возвращаемому значению.

Если вы хотите избежать копирования или перемещения возвращенной строки и можете принять копию, то использование обычного объекта так же хорошо, как ссылка на константу.