Что происходит в C ++, если вы передаете анонимный объект в функцию, которая принимает ссылку? - PullRequest
3 голосов
/ 02 сентября 2010

IE, что произойдет, если у вас есть следующий фрагмент кода?

int mean(const vector<int> & data) {
  int res = 0;
  for(size_t i = 0; i< data.size(); i++) {
    res += data[i];
  }
  return res/data.size();
}

vector<int> makeRandomData() {
  vector<int> stuff;
  int numInts = rand()%100;
  for(int i = 0; i< numInts; i++) {
    stuff.push_back(rand()%100);
  }
}

void someRandomFunction() {
  int results = mean(makeRandomData());
}

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

Кроме того, как это работает / мешает RVO?

Заранее спасибо.

РЕДАКТИРОВАНИЕ: Добавлено const, забыл вставить это.

Ответы [ 2 ]

15 голосов
/ 02 сентября 2010

Мои экстрасенсорные способности говорят мне, что вы компилируете это на Visual C ++, поэтому это даже работает.В стандартном C ++ вы не можете передать rvalue (то есть значение, возвращаемое makeRandomData) для ссылки на non-const, поэтому вопрос спорный.

Однако вопрос по-прежнемудействителен, если вы измените подпись mean на const vector<int>&.В этом случае все сводится к времени жизни временного объекта, которое определено как последний до конца «полного выражения», в котором оно происходит.В вашем конкретном случае полное выражение - это полный инициализатор results.В случае оператора выражения, полное выражение - это все выражение.

Стандарт не указывает каким-либо образом, каким образом аргументы функции могут препятствовать RVO, но, конечно, RVO - это мандат, который компилятор должен выполнятьопределенная оптимизация независимо от видимых побочных эффектов, а не требование , чтобы сделать это.Когда (и если) происходит RVO, полностью зависит от используемого вами компилятора.Тем не менее, кажется, нет никаких причин, почему это должно каким-либо образом повлиять на это.

4 голосов
/ 02 сентября 2010

В C ++ вы не можете передать временный объект в функцию, которая принимает непостоянную ссылку.Приведенный выше пример не будет компилироваться.Если ваш компилятор его компилирует, это причуда (расширение) вашего компилятора.Если ваш компилятор скомпилирует его даже без выдачи диагностического сообщения, ваш компилятор сломан.

Временный объект (результат вашего вызова makeRandomData()) может быть передан в mean только через ссылку с квалификацией const,Т.е. ваш mean должен быть объявлен как

int mean(const vector<int> & data) 

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...