Являются ли все временные значения rvalues в C ++?

StackOverflow https://stackoverflow.com/questions/2145030

  •  23-09-2019
  •  | 
  •  

Вопрос

Последние несколько лет я занимаюсь программированием на C ++.Но есть один вопрос, на который я так и не смог ответить.Я хочу спросить, все ли временные значения в C ++ равны rvalues?

Если нет, может ли кто-нибудь привести мне пример, когда временное значение, создаваемое в коде, является значение lvalue?

Это было полезно?

Решение

Нет.

Спецификация языка C ++ никогда не делает такое простое утверждение, как то, о котором вы спрашиваете. Он нигде не говорится в стандарте языка, что «все временные объекты - это RValues». Более того, сам вопрос немного неправильно, поскольку свойство того, чтобы быть RVALUE на языке C ++, является не свойством объекта, а скорее свойством выражения (то есть свойство его результата). Это на самом деле то, как это определено в спецификации языка: для различных видов выражений это говорит о том, когда результат является LVALUE и когда это RVALUE. Среди прочего, это фактически означает, что временный объект можно получить как RValue, а также LVALUE, в зависимости от конкретной формы выражения, которая используется для выполнения доступа.

Например, результат буквального 2 + 3 Выражение, очевидно, является RValue, временным типом int. Анкет Мы не можем применить Unary & к этому, так как & требуется lvalue в качестве операнда

&(2 + 3); // ERROR, lvalue required

Однако, как мы все знаем, постоянная ссылка может быть прикреплена к временному объекту, как в

const int &ri = 2 + 3;

В этом случае ссылка прикреплена ко временным, продлевая срок службы последнего. Очевидно, что как только это будет сделано, у нас есть доступ к тому же временно, что и LVALUE ri, поскольку ссылки всегда являются Lvalues. Например, мы можем легко и законно применить Unary & на ссылку и получить указатель на временный

const int *pi = &ri;

С этим указателем остается совершенно действительным, пока временный упорство.

Еще один очевидный пример доступа к временному объекту - это когда мы получаем доступ ко временному объекту типа класса через его this указатель. Результат *this это lvalue (как всегда в случае с результатом Unary * Применяется к указателю данных), но это не меняет того факта, что фактический объект может легко быть временным. Для данного типа класса T, выражение T() является RVALUE, как явно указано в языковом стандарте, но временный объект доступ к *T().get_this() выражение (с очевидной реализацией T::get_this()) это lvalue. В отличие от предыдущего примера, этот метод позволяет немедленно получить LVALUE, не содержащий квалификации, который относится к временному объекту.

Таким образом, еще раз, тот же самый временный объект может быть легко «рассматриваться» как RVALUE или как LVALUE в зависимости от того, какое выражение (какое Путь доступа) вы используете, чтобы «смотреть» на этот объект.

Другие советы

Prasoon Saurav уже связал очень хорошую потоку CLC ++. Там Джеймс Канзе объясняет, почему вопрос не имеет смысла. Это сводится к:

  • rvalue -ness - это (логическое) свойство выражений - каждое выражение является либо LVALUE, либо RVALUE
  • Временные есть нет выражения

По этой причине вопрос не имеет смысла.

Хорошим примером является следующий код:

int main() {
  const int& ri = 4;
  std::cout << ri << std::endl; 
}

Временный int с стоимостью 4 не является выражением. Выражение ri Это напечатано не временное. Это LVALUE, и относится к временному.

Что ж, этот оператор массива возвращает ссылку, любая функция, которая возвращает ссылку, можно считать, чтобы сделать то же самое? Все ссылки являются const, в то время как они могут быть Lvalues, они изменяют то, что они ссылаются, а не сами ссылка. То же самое верно для *оператор,

*(a temp pointer) = val;

Клянусь, я использовал какой -то компилятор, который передал бы значения температуры любой функции, которая взяла на себя ссылку,

Итак, вы могли бы пойти:

int Afunc()
{
   return 5;
}

int anotherFunc(int & b)
{
    b = 34;
}


anotherFunc(Afunc());

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

int anotherFunc(const int & b);

В любом случае, ссылки могут быть LVALUEST и временным, и это уловка, заключающаяся в том, что он сам не изменяется, только то, что он ссылается.

Если вы считаете-> Оператор в качестве оператора, тогда временные указатели могут быть LVALUES, но применяется то же условие, это не тот временный указатель, который будет изменен, а на то, на что он указывает.

Операция индексации массива - это временная и LVALUE, что -то вроде [10] = 1 является примером того, что вы ищете; LVALUE является временным, рассчитанным указателем.

Краткий ответ:да, но я не собираюсь цитировать стандарт, потому что для доказательства этой точки зрения потребовалось бы рассмотреть все возможные временные проблемы.По определению, временное значение имеет срок службы одного оператора, поэтому присваивать что-либо одному было бы в лучшем случае некачественным стилем.

Интересный ответ:Устранение копирования может сделать (часто делает) временный объект идентичным объекту lvalue.Например,

MyClass blah = MyClass( 3 ); // temporary likely to be optimized out

или

return MyClass( 3 ); // likely to directly initialize object in caller's frame

Редактировать: что касается вопроса о том, существует ли в этих случаях какой-либо временный объект, в §12.8/15 упоминается

операция копирования может быть опущена путем создания временного объекта непосредственно в целевом объекте опущенной копии

это указывало бы на то, что существует временный объект, который может быть идентичен значению lvalue.

SharePoint Designer предоставляет сборник рабочих процессов, которые доступны через пользовательский интерфейс рабочего процесса Designer (UI). Хотя ассортимент рабочих процессов, которые включены в дизайнер SharePoint, обширно, это все же конечное. В некоторых случаях вам может потребоваться моделировать бизнес-процесс, требования которого не выполняются существующей библиотекой действий рабочего процесса, которые доступны в SharePoint Designer.

Вы можете взглянуть на ссылки ниже,

Лучшие практики для создания пользовательских Деятельность в SharePoint 2010

Полезный дизайнер SharePoint Designer пользовательских рабочих процессов. -> В этом вы можете использовать «Отправить Электронная почта с активностью вложения HTTP-файла "-> Эта деятельность позволяет отправлять электронные письма с навесами, полученными с использованием веб-запроса. Выполнение отчетов о отчетности в отчетности и отправка его в качестве приложения из рабочего процесса SPD будет одним из таких примеров. URL-адрес запроса полностью настраивается и может включать переменные рабочие процессы. Поддерживаются как запросы HTTP, так и HTTPS. Отказ

SharePoint 2010: Создайте активность рабочего процесса с помощью Visual Studio 2010

Пользовательские мероприятия дизайнера SharePoint для SharePoint 2010.

Как мне создать пользовательские действия Для рабочего процесса?

Если нет, может ли кто -нибудь привести мне пример, в котором временное создание в коде - это LVALUE?

Следующий код связывает постоянную ссылку на временный объект типа const float Создано компилятором:

int i;
const float &cfr = i;

Поведение "как будто":

int i;
const float __tmp_cfr = i; // introduced by the compiler
const float &cfr = __tmp_cfr;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top