C ++ - нет совпадения для оператора = при компиляции с использованием GCC - PullRequest
3 голосов
/ 20 мая 2010

Я недавно пытался создать свои собственные общие и слабые указатели. Код, который компилируется с использованием Visual Studio, не компилируется в GCC (4.5.0) со следующей ошибкой:

main.cpp: In function 'int main()':
main.cpp:18:27: error: no match for 'operator=' in 'wp1 = weak_ptr<int>(((const shared_ptr<int>&)((const shared_ptr<int>*)(& sp1))))'
weak_ptr.h:59:9: note: candidate is: void weak_ptr<T>::operator=(weak_ptr<T>&) [with T = int, weak_ptr<T> = weak_ptr<int>]

Вот самые важные части моего кода:

1) Слабая реализация указателя (обратите внимание на объявление operator=)

#include "smart_ptr_wrapper.hpp"
#include "shared_ptr.h"

template <typename T>
class weak_ptr {
private:
   // Weak wrapper implementation
   typedef smart_ptr_wrapper<T> weak_ptr_wrapper;
   weak_ptr_wrapper* wrapper;

private:
   // Shared wrapper additional routines
   void increase_reference_count() {
      ++(wrapper->weak_count);
   }
   void decrease_reference_count() {
      --(wrapper->weak_count);

      // Dispose the wrapper if there are no more
      // references to this object
      // @note This should actually lock the wrapper to
      // preserve thread safety
      if (wrapper->strong_count == 0 && wrapper->weak_count == 0) {
         delete wrapper;
      }
   }

public:
   // Default constructor to grant syntax flexibility
   weak_ptr() : wrapper(NULL) { }

   weak_ptr(const shared_ptr<T>& pointer) : wrapper(pointer.wrapper) {
      increase_reference_count();
   }

   weak_ptr(const weak_ptr& p) : wrapper(p.wrapper) {
      increase_reference_count();
   }

   weak_ptr& operator= (weak_ptr& p) {
      // Set new reference counts
      // @note If this is 'just-a-pointer', which was created
      // using default constructor then our wrapper would be 'NULL'
      if (wrapper != NULL) {
         decrease_reference_count();
      }
      p.increase_reference_count();
      // Set new wrapper
      wrapper = p.wrapper;

      return *this;
   }

   ~weak_ptr() {
      decrease_reference_count();
   }

   T* get() const { return (wrapper->strong_count == 0) ? NULL: wrapper->raw_pointer; }
   T* operator-> () const { return  get(); }
   T& operator*  () const { return *get(); }

   // User comparison operation
   operator void* () const {
      return (get() == NULL);
   }
};

2) main.cpp

int main() {
   shared_ptr<int> sp1(new int(4));
   weak_ptr<int> wp1(sp1);
   // Next line can't be compiled by gcc... Why?
   wp1 = weak_ptr<int>(sp1);
   return 0;
}

Q

Почему это происходит? Я, вероятно, просто глуп, но я не вижу, что не так с этим кодом, и не могу понять поведение GCC. Я также был бы признателен, если бы кто-то мог объяснить, почему этот код компилируется и почему он работает под MSVS (я имею в виду, почему один компилятор справляется с этим и почему второй отказывает). Спасибо.

Обновление: полный код и ошибка компилятора можно увидеть здесь - http://codepad.org/MirlNayf

Ответы [ 2 ]

5 голосов
/ 20 мая 2010

Ваш оператор присваивания требует ссылку, а не ссылку const:

weak_ptr& operator= (weak_ptr& p)

Однако выражение weak_ptr<int>(sp1) приводит к временному результату, который может быть преобразован только в ссылку const, так как это значение r. Подумайте об этом так: вы не можете изменить результат выражения, но ваш оператор присваивания требует, чтобы это было возможно.

Решение состоит в том, чтобы объявить ваш оператор присваивания следующим образом:

weak_ptr& operator= (const weak_ptr& p)

Почему VC ++ допускает, что это вне меня ... возможно, вам следует включить некоторые флаги соответствия стандартам.

0 голосов
/ 20 мая 2010

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

...