перегрузка оператора << в C работает не так, как ожидалось

#c #operator-overloading #operator-keyword

#c #перегрузка оператора #operator-ключевое слово

Вопрос:

Я определил шаблон класса MyVector и перегрузил operator<< его для печати вектора, который он содержит.

 //MyVector definition
template<int n, typename T>
class MyVector{


  private:
    vector<T> vetor;
  public:
    //Several Methods
    MyVector operator (MyVectoramp; v){
        //Adds 2 vectors
    }

   template<typename U, int m>
   friend ostreamamp; operator << (ostreamamp; o, MyVector<m,U>amp; v);
};

template<typename T, int n>
ostreamamp; operator << (ostreamamp; o, MyVector<n,T> amp;v){
  o << "[";
  for(auto itr = v.vetor.begin(); itr != v.vetor.end()-1;   itr){
    o << *itr <<", ";
  }
  o << v.vetor.back() << "]";
  return o;
}
  

Оператор, похоже, отлично работает для простых вариантов использования, но при добавлении 2 экземпляров MyVector operator<< выдает:

 invalid operands to binary expression
  
 int main(){
  MyVector<2,int> v1;
  MyVector<2,int> v2;
  MyVector<2,int> v3;

  v1.add(1,2);
  v2.add(3,4);
  v3 = v1 v2;

  cout << v3 << endl;  // --> This prints "[7,11]" to the console
  cout << v1 v2 << endl; // --> This throws the exception
}
  

Чего мне здесь не хватает?

Комментарии:

1. Вы должны передавать параметр в качестве ссылки lvalue только тогда, когда у вас есть намерение его изменить. В любом другом случае либо передавайте по значению, либо по постоянной ссылке (чтобы избежать дорогостоящего копирования)

Ответ №1:

Ваш operator on MyVector возвращает временный:

    MyVector operator (MyVectoramp; v);
// ^^^^^^^^ temporary 
  

который не может привязываться к неконстантной ссылке, которая operator<< ожидает:

 ostreamamp; operator << (ostreamamp; o, MyVector<m,U>amp; v);
                               // ^^^^^^^^^^^^^^  non-const reference
  

Вы можете исправить это, приняв вместо этого ссылку const:

 ostreamamp; operator << (ostreamamp; o, MyVector<m,U> const amp; v);
                                             // ^^^^^
  

Аналогично, ваш operator должен принимать его аргумент по ссылке const, а также должен иметь значение const:

 MyVector operator (MyVector const amp; v) const;
                         // ^^^^^      ^^^^^
  

чтобы разрешить работу подобных выражений:

 MyVector<2, int> const v = // ...
std::cout << v   v   v;
  

Комментарии:

1. operator параметр также должен быть const ссылкой, чтобы предотвратить следующий вопрос, a b c почему не работает.

2. Большое спасибо!!! Это было очень полезно, я новичок в C , и мне все еще трудно понять эти параметры «const».

3. Нет проблем 🙂 Рассмотрите возможность принятия ответа, если он отвечает на ваш вопрос.