Добавление векторов c ++.Не могу понять ошибку компиляции - PullRequest
1 голос
/ 22 сентября 2011

Привет, я написал следующую функцию для добавления 2 векторов

vector<double> add(vector<double>& v1, vector<double>& v2 )

{  /*Do quick size check on vectors before proceeding*/

  vector<double> result(v1.size());
  for (unsigned int i = 0; i < result.size(); ++i)
  {
    result[i]=v1[i]+v2[i];
  }

  return result;

}

Теперь я попытался добавить 3 вектора a, b, c одинакового размера следующими двумя способами

vector <double> sum1, sum2;

sum1=add(b,c);

sum2=add(a,sum1); 

, который работал

и

vector <double> sum;
sum=add(a,add(b,c));

, который дал мне следующую ошибку компилятора

g++ -Wall simple.cpp 
simple.cpp: In function ‘int main(int, char**)’:
simple.cpp:45: error: invalid initialization of non-const reference of type ‘std::vector<double, std::allocator<double> >&’ from a temporary of type ‘std::vector<double, std::allocator<double> >’
simple.cpp:16: error: in passing argument 2 of ‘std::vector<double, std::allocator<double> > add(std::vector<double, std::allocator<double> >&, std::vector<double, std::allocator<double> >&)’

Почему второй метод не работает?

Ответы [ 2 ]

7 голосов
/ 22 сентября 2011
vector<double> add(vector<double> v1, vector<double> v2 )

Из сообщения об ошибке я могу с уверенностью сказать, что это не сигнатура функции в вашем исходном коде.

В исходном коде вы должны использовать это:

vector<double> add(vector<double> & v1, vector<double>  & v2 )

Если это так, сделайте его следующим образом:

vector<double> add(const vector<double> & v1, const vector<double>  & v2)

Теперь все должно работать нормально.

Объяснение:

Возвращаемое значение add() является временным объектом, и временный объект не может быть привязан к неконстантной ссылке.Вот почему компилятор выдавал ошибку.Это даст ту же ошибку, если вы напишите это:

vector<double> & v = add(a,b); //error 

Однако, если временный объект может быть связан со ссылкой const.Вот почему я предложил вам сделать ссылку на параметр const.Это означает, что вы можете написать это:

const vector<double> & v = add(a,b); //ok

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

Лучшее решение таково:

vector<double> add(const vector<double> & v1, const vector<double>  & v2)

Знакомство с оператором +

Вы также можете перегрузить operator+ для вектора, например:

vector<double> operator + (const vector<double>& v1, const vector<double>& v2 )
{  
  /*Do quick size check on vectors before proceeding*/
  vector<double> result(v1.size());
  for (unsigned int i = 0; i < result.size(); ++i)
  {
    result[i]=v1[i]+v2[i];
  }
  return result;
}

Если вы перегрузите это, то вы можете написать этот классный код:

vector<double> c = a + b;
vector<double> d = a + b + c;
vector<double> e = a + b + c + d;
//so on

Isnне правда ли?

Знакомство со стандартным алгоритмом ..

Как прокомментировал @Gene, вы можете использовать std::transform в функции как:

vector<double> operator+(const vector<double>& v1, const vector<double>& v2 )
{  
   vector<double> result;
   std::transform(v1.begin(),v1.end(),v2.begin(), 
                            std::back_inserter(result), std::plus<double>);
   return result;
}
0 голосов
/ 22 сентября 2011
vector<double> add(vector<double>& v1, vector<double>& v2 )

Поскольку мы ожидаем, что функция изменит свои аргументы, мы не можем вызывать функцию только с каким-либо выражением.Вместо этого мы должны передать аргумент lvalue в ссылочный параметр.Lvalue - это значение, которое обозначает нетрадиционный объект.

sum=add(a,add(b,c));

Предыдущий вызов add пытается передать временный объект.

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