2010-05-20 42 views
3

我最近嘗試構建自己的共享和弱指針。可以編譯使用Visual Studio在GCC(4.5.0)不編譯下面的錯誤代碼:C++ - 使用GCC編譯時'operator ='不匹配

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; 
} 

問:

爲什麼會發生這種情況?我可能很愚蠢,但我看不出這個代碼有什麼問題,並且無法解決GCC行爲。我也很感激,如果有人能解釋爲什麼這個代碼會編譯,爲什麼它能在MSVS下工作(我的意思是,爲什麼一個編譯器可以很好地工作,爲什麼還會失敗)。謝謝。

更新:完整的代碼和編譯器錯誤在這裏可以看到 - http://codepad.org/MirlNayf

+0

在GCC中工作(http://codepad.org/GUdC3D0L) – 2010-05-20 16:58:22

+0

由於舊的編譯器擴展,它適用於MSVC++。禁用擴展,並且它也會在MSVC中失敗。 – AnT 2010-05-20 17:03:03

回答

5

你的賦值運算符需要一個參考,而不是一個const參考:

weak_ptr& operator= (weak_ptr& p) 

然而,表達weak_ptr<int>(sp1)導致暫時的,它只能被轉換爲const引用,因爲它是一個右值。這樣想一下:你不能修改表達式的結果,但你的賦值操作符要求它可以。

解決的辦法是宣佈你的賦值運算符是這樣,而不是:

weak_ptr& operator= (const weak_ptr& p) 

爲什麼VC++接受這已經超出了我......也許你應該讓一些標準符合性標誌。

+0

MS調用VC綁定rvalues到non-'const'引用一個「擴展」的事實。我認爲這是一個錯誤。 – sbi 2010-05-20 17:35:30

0

這是因爲您首先從sp1構建了一個新對象,然後分配它,這不是我期望的預期行爲。但是,根本的錯誤是因爲賦值應該採用const引用。