2015-02-05 21 views
3

這是指針到實現代碼一個最小化的部分:克++ 4.9.2迴歸上通參照「這個」

template<typename T> 
class PImpl { 
private: 
    T* m; 
public: 

    template<typename A1> 
    PImpl(A1& a1) : m(new T(a1)) { 
    } 
}; 

struct A{ 
    struct AImpl; 
    PImpl<AImpl> me; 
    A(); 
}; 

struct A::AImpl{ 
    const A* ppub; 
    AImpl(const A* ppub) 
    :ppub(ppub){} 
}; 
A::A():me(this){} 

A a; 
int main (int, char**){ 
    return 0; 
} 

它上G ++ 4.8和現有可編譯和工程,以及。但是G ++ 4.9.2編譯器會產生以下錯誤:

prog.cpp: In constructor 'A::A()': 
prog.cpp:24:15: error: no matching function for call to 'PImpl<A::AImpl>::PImpl(A*)' 
A::A():me(this){} 
      ^
prog.cpp:24:15: note: candidates are: 
prog.cpp:9:5: note: PImpl<T>::PImpl(A1&) [with A1 = A*; T = A::AImpl] 
    > PImpl(A1& a1) : m(new T(a1)) { 
    ^
prog.cpp:9:5: note: no known conversion for argument 1 from 'A*' to 'A*&' 
prog.cpp:2:7: note: PImpl<A::AImpl>::PImpl(const PImpl<A::AImpl>&) 
class PImpl { 
    ^
prog.cpp:2:7: note: no known conversion for argument 1 from 'A*' to 'const PImpl<A::AImpl>&' 

但是它可以通過小黑客來修復。如果我通過'& *此'而不是'',那麼它會帶來可編譯狀態。

是G ++迴歸還是新的C++標準功能,它消除了向後兼容性?

回答

1

這並沒有爲我編譯gcc-4.6,所以看起來gcc-4.8是迴歸發生的地方。看來你想要的是通過通用參考A1,即:PImpl(A1 && a1)。這爲我編譯gcc-4.6,gcc-4.8和gcc-4.9。

+0

它編譯在gcc-4.3.2上:http://ideone.com/nKcI6m – slonma 2015-02-06 07:08:28

3

我們可以使編譯上既不克++ 4.9也不鐺一個簡單的例子:

template <typename T> 
void call(T&) { } 

struct A { 
    void foo() { call(this); } 
}; 

int main() 
{ 
    A().foo(); 
} 

這是因爲this是,從標準,[class.this](§9.3.2):

In the body of a non-static (9.3) member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called.

你不能把一個左值參照prvalue,因此錯誤 - 這GCC解釋比鐺在這種情況下更好:

error: invalid initialization of non-const reference of type A*& from an rvalue of type A*

如果我們將call重寫爲const T&T&&,則兩個編譯器都會接受該代碼。

+0

爲什麼'&* this'有效? – 0x499602D2 2015-02-05 18:57:57

+0

@ 0x499602D2因爲'* this'是一個左值。 – Barry 2015-02-05 19:12:52

+0

但'&x'返回一個prvalue。 – 0x499602D2 2015-02-05 19:41:01