2015-02-05 4 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>&' 

그러나 작은 해킹으로 고칠 수 있습니다. ''대신 '& * this'을 전달하면 컴파일 가능한 상태가됩니다.

역 호환성을 제거하는 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

3

우리는 둘 다 g에 컴파일 ++ 4.9이나 그 소리를 간단한 예제를 만들 수 있습니다 this 표준에서이기 때문이다

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

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

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

, [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*

을 다시 작성하여 const T& 또는 T&&을 사용하면 두 컴파일러 모두 코드를 허용합니다.

+0

왜 '& * this'가 작동 했나요? – 0x499602D2

+0

@ 0x499602D2'* this'는 좌변 값이기 때문에. – Barry

+0

그러나'& x'는 prvalue를 반환합니다. – 0x499602D2