Взятие адреса временного объекта

Унарные операторы §5.3.1, Раздел 3

Результатом унарного и оператора является указатель на свой операнд. Операнд должен быть lvalue или квалифицированным идентификатором.

То, что точно делает, "должно быть" средним в этом контексте? Это означает, что это - ошибка взять адрес временного файла? Я просто задавался вопросом, потому что g ++ только дает мне предупреждение, тогда как comeau отказывается компилировать следующую программу:

#include <string>

int main()
{
    &std::string("test");
}

g ++ предупреждение: taking address of temporary

ошибка comeau: expression must be an lvalue or a function designator

Кто-либо имеет компилятор Microsoft или другие компиляторы и может протестировать эту программу?

24
задан Dharman 18 August 2019 в 20:03
поделиться

6 ответов

Слово «должен» на стандартном языке означает строгое требование. Итак, да, ваш код плохо сформирован (это ошибка), потому что он пытается применить оператор адресации к не-lvalue.

Однако проблема здесь не в попытке взятия адреса временного . Проблема, опять же, в том, что адрес не является lvalue . Временный объект может быть lvalue или отличным от lvalue в зависимости от выражения, которое создает этот временный объект или предоставляет доступ к этому временному объекту. В вашем случае у вас есть std :: string ("test") - приведение функционального стиля к не ссылочному типу, который по определению производит не-lvalue. Отсюда ошибка.

Если вы хотите получить адрес временного объекта, вы могли бы обойти ограничение, сделав это, например

const std::string &r = std::string("test");
&r; // this expression produces address of a temporary

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

26
ответ дан 28 November 2019 в 23:49
поделиться

Я не специалист по стандартам, но это безусловно, звучит для меня как ошибка. g ++ очень часто выдает предупреждение только о том, что действительно является ошибкой.

0
ответ дан 28 November 2019 в 23:49
поделиться

Это разрешено в MSVC с устаревшей опцией / Ze (расширения включены). Это было разрешено в предыдущих версиях MSVC. Он генерирует диагностику со всеми включенными предупреждениями:

предупреждение C4238: использовано нестандартное расширение: класс rvalue используется как lvalue.

Если не используется параметр / Za (обеспечение совместимости с ANSI), то:

ошибка C2102: '&' требует l-значения

3
ответ дан 28 November 2019 в 23:49
поделиться

& std :: string ("test"); запрашивает адрес возвращаемое значение вызова функции (мы проигнорируем как несущественный факт, что эта функция является ctor). У него не было адреса, пока вы его чему-то не присвоили. Значит, это ошибка.

1
ответ дан 28 November 2019 в 23:49
поделиться

: h scroll-cursor

Ответ Джонатана действителен, однако я предпочитаю zt (в качестве «верхнего»), который держит курсор на месте. В этой же идее есть zb (как «низ») и zz (не как «середина», но это ставит текущую линию в центр окна).

-121--1199660-

Попробуйте использовать codeigniter 'site _ url' в действии, чтобы убедиться, что вы указываете нужное место. Действие в примере должно было перейти к контроллеру поиска, а не к контроллеру формы. Индекс

<html>
<head>
<title>Search</title>
</head>
<body>
<form action="<?= site_url('form/process_search') ?>">
<input type="text" name="search" value="" size="50" />
<div><input type="submit" value="Submit" /></div>
</form>
</body>
</html>

используется в контроллере только тогда, когда больше ничего не передается. Так что в случае моего примера выше вы бы хотели что-то подобное:

function Form()
{
    parent::Controller();   
}

function process_search()
{   

     print "<pre>";

     print_r($_POST);

     print "</pre>";
}
-121--1880542-

Стандарт C++ на самом деле является требованием для соответствующих реализаций C++. В местах он записывается, чтобы различать код, который должны принимать реализации Conformant, и код, для которого реализации Conformant должны давать диагностику.

Так, в данном конкретном случае, конформный компилятор должен дать диагностику, если взят адрес значения rvalue. Оба компилятора так и делают, поэтому они согласуются в этом отношении.

Стандарт не запрещает создание исполняемого файла, если определенный ввод вызывает диагностику, т.е. предупреждения являются допустимой диагностикой.

1
ответ дан 28 November 2019 в 23:49
поделиться

Когда в стандарте C++ используется слово "shall", оно означает "должен под страхом смерти" - если реализация не подчиняется этому, она ошибочна.

5
ответ дан 28 November 2019 в 23:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: