Можно ли явно привести prvalue к константной ссылке, чтобы избежать дополнительного копирования в тернарном операторе?C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Можно ли явно привести prvalue к константной ссылке, чтобы избежать дополнительного копирования в тернарном операторе?

Сообщение Anonymous »


Предположим, у нас есть некоторый некопируемый и неперемещаемый тип Foo и функция

int f(const Foo& foo) { ... // каким-то образом вычисляем результат в зависимости от значения foo. } Теперь предположим, что мы хотим вызвать эту функцию следующим образом:

const Foo foo1{ 42 }; логическое условие = getCondition(); int result = f (условие? foo: Foo {150}); Это не скомпилируется, поскольку foo и Foo{ 150 относятся к разным категориям значений, поэтому по определению тернарный оператор вернет prvalue типа < code>Foo — это означает, что foo1 необходимо будет скопировать, если condition == true, поэтому это вызывает ошибку компиляции.

Однако C++ гарантирует, что временные объекты остаются действительными до конца выражения, поэтому вместо этого мы можем написать следующее:

const Foo foo1{ 42 }; логическое условие = getCondition(); int result = f (условие? foo: static_cast(Foo{ 150 }); Теперь тернарный оператор возвращает const Foo&, и даже если эта ссылка ссылается на Foo{ 150 , этот временный объект останется действительным до конца выражения. Никакого копирования/перемещения не происходит, поэтому это компилируется.

Очевидно, безопаснее было бы просто написать:

int result = условие? е(фу): е(фу{150}); Однако это может привести к появлению большого количества шаблонов, если есть дополнительные параметры, и экспоненциально растет для нескольких «условных» параметров:

int result =condition1 ? (условие2 ? f(foo1, foo2) : f(foo1, Foo{ 222 })) : (условие2 ? f(Foo{ 111 }, foo2): f(Foo{ 111 }, Foo{ 222 })); Приведенный выше хак позволяет использовать более короткую форму:

int result = f(condition1? foo1: static_cast(Foo{ 111 }), условие2 ? foo2 : static_cast(Foo{ 222 }) ); Я понимаю, что это сопряжено с некоторым риском, но правильно ли я считаю, что приведенный выше код действителен?

П.С. Мне также интересно, генерирует ли компилятор инструкции O(N) или O(2^N) при наличии N таких «условных» параметров.

Тернарный оператор и продление времени жизни временного объекта с помощью ссылки на константу рассматривают аналогичный сценарий, но вопрос в том, продлевает ли сам тернарный оператор время жизни временного объекта - это не так.
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»