2013-04-29 3 views
18

Является ли следующая функция безопасной в C++ 03 или C++ 11 или она отображает UB?Передача справки через функцию безопасна?

string const &min(string const &a, string const &b) { 
    return a < b ? a : b; 
} 

int main() { 
    cout << min("A", "B"); 
} 
  • Допустимо ли возвращать ссылку на объект передается функции по ссылке?

  • Гарантировано, что временный объект string не был уничтожен слишком рано?

  • Есть ли вероятность, что данная функция min может отображать UB (если это не в данном контексте)?

  • Можно ли сделать эквивалентную, но безопасную функцию, избегая при этом копирования или перемещения?

+0

Вам нужно работать со строковыми строками? Если вы абсолютно хотите избежать временных ситуаций, вы можете использовать '' std :: strcmp() ''. – bluescarni

+0

@bluescarni: Не имеет значения, существует ли «string» или другой тип временного объекта. Вопрос должен быть общим. –

ответ

29

Можно ли вернуть ссылку на объект, переданный функции по ссылке?

До тех пор, пока объект не будет уничтожен, прежде чем вы получите доступ к нему через эту ссылку, да.

Гарантировано, что временный объект string не будет уничтожен слишком рано?

В этом случае да. Временное продолжается до конца полного выражения, которое его создает, поэтому оно не уничтожается до после того, как передается в cout.

Есть ли вероятность, что данная функция min может отображать UB (если она не в данном контексте)?

Да, вот пример:

auto const & r = min("A", "B"); // r is a reference to one of the temporaries 
cout << r;      // Whoops! Both temporaries have been destroyed 

Можно ли сделать эквивалент, но безопасной функции в то же время избегая копирования или перемещения?

Я так не думаю; но эта функция безопасна, пока вы не держите ссылку на ее результат.

+1

Я уверен, что невозможно сделать эквивалент, потому что для этого потребуется полный GC. Вам нужно отслеживать, имеются ли ссылки на временный объект. – MSalters

+1

Функция сама по себе не делает ничего неопределенного (возвращаемая ссылка будет действительной до тех пор, пока это будут параметры) ... ее использование делает IMO – nishantjr

+0

В этом случае компилятору разрешено копировать копию, если это возможно. Однако это зависит от вашего уровня компилятора и оптимизации. Например, GCC предотвратит копирование временных возвращаемых значений с помощью -O2 или выше. – Symaxion

2

Да, это безопасно. Темп последовательности для «А» и «В» сохранится до конца «точки последовательности», то есть точки с запятой.

4

Ваших временные объекты будут оставаться «живыми» до конца ; от cout в основном, так этого способа использования безопасно.

1

Это гарантирует, что временный строковый объект не уничтожается слишком скоро

Для вашего конкретного случая да, но следующий код не

int main() { 
    const string &tempString(min("A", "B")); 
    cout << tempString; 
} 

Кроме этого, я согласен с что сказал Майк Сеймур.

+1

Если бы было ключевое слово const для этой временной ссылки –

+0

Спасибо, теперь она компилируется и показывает случай, где проблема. –

0

Да, это безопасно передать ссылку через функцию, потому что в изменениях, всегда внесенных в аргументы, которые вы передаете по значению, и в приведенной выше последовательности строк темп для А и Б сохранится до конца «точки последовательности», то есть точку с запятой, но в случае передачи по ссылке изменений, сделанных в копии этого аргумента, не в оригинальной копии.

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