2015-06-26 10 views
4

Я написал функцию, как показано ниже:C++ 11 Кортеж с копией элизии или переместить семантический

template <typename T> 
std::tuple<std::vector<T>, T, T> f() { 
    std::vector<T> p(1000); 
    return std::make_tuple(std::move(p), 10, 10); 
} 

Поскольку тип возвращаемого является довольно сложным, это гарантировано, что в C++ 11 компилятор либо применить скопировать elision или переместить семантику, когда она конструирует результат, или я должен явно сказать что-то вроде std :: move (std :: make_tuple (std :: move (p), 10, 10))?

+0

Не уверен, поэтому это не ответ: копия elision гарантируется при использовании именованных переменных. Вместо этого используйте ссылки rvalue, такие как: std :: make_tuple (std :: vector (1000), 10, 10); поэтому удаление переменной. Компилятор выполнит копирование. При использовании переменных это не гарантируется, а оптимизация, поэтому зависит от компилятора. – LoPiTaL

+0

@LoPiTaL При выполнении 'return std :: make_tuple (...)' возвращаемое значение перемещается из временного. В 'auto x = f ();', 'x' перемещается из возвращаемого значения. Копирование elision позволяет компилятору опустить один из этих * ходов *. Ни в коем случае не будет скопирован «вектор», независимо от оптимизации. –

+0

Как вы думаете, std :: move (p) избыточен? Я пробовал что-то вроде auto x = std :: make_tuple (std :: move (p), 10, 10), и я обнаружил, что он делает копию p (путем проверки размера p). –

ответ

1

AFAIK copy elision всегда является необязательным. Стандарт просто прямо говорит, что компилятор разрешает такую ​​оптимизацию, потому что он изменяет наблюдаемое поведение, он не дает ему мандат. В частности, 12,8 с. 31:

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

Отказ от ответственности: Это из сообщества проекта n3690, но версия для C++ 11 имеет аналогичное утверждение, если не точно такой же.

Кстати, критерии указаны прямо там.

Для перемещения, однако, это гарантировано. Вы создаете временный объект и возвращаете его (т. Е. std::make_tuple возвращает rvalue, и вы передаете его вперед), аргументы шаблона не меняют поддержку семантики перемещения.

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

  • Нет связанных вопросов^_^