2009-10-16 73 views
1

我試圖使用PIMPL方法隱藏一些蹩腳的模板代碼,但我不能給身體類朋友訪問手柄類派生類。我從MSVC 9 sp1中收到錯誤C2248。下面是一些代碼複製的錯誤:PIMPL方法和模板類的朋友

// 
// interface.hpp 
// 
namespace internal{ 
    template<class T> 
    class specific_body; 
} 

class interface 
{ 
    struct body; 
    body *pbody_; 
    interface(body *pbody); 

    template<class T> 
    friend class internal::specific_body; 

public: 

    ~interface(); 

    interface(const interface &rhs); 

    bool test() const; 

    static interface create(bool value); 
}; 

// 
// interface.cpp 
// 
struct interface::body 
{ 
    virtual ~body(){} 

    virtual bool test() const = 0; 

    virtual interface::body *clone() const = 0; 
}; 

class true_struct {}; 
class false_struct {}; 

namespace internal { 

template< class T> 
class specific_body : public interface::body 
{ // C2248 
public: 

    specific_body(){} 

    virtual bool test() const; 

    virtual interface::body *clone() const 
    { 
     return new specific_body(); 
    } 
}; 

bool specific_body<true_struct>::test() const 
{ 
    return true; 
} 

bool specific_body<false_struct>::test() const 
{ 
    return false; 
} 

} //namespace internal 

interface::interface(body *pbody) : pbody_(pbody) {} 

interface::interface(const interface &rhs) : pbody_(rhs.pbody_->clone()) {} 

interface::~interface() { delete pbody_; } 

bool interface::test() const 
{ 
    return pbody_->test(); 
} 

interface interface::create(bool value) 
{ 
    if (value) 
    { 
     return interface(new internal::specific_body<true_struct>()); 
    } 
    else 
    { 
     return interface(new internal::specific_body<false_struct>()); 
    } 
} 

// 
// main.cpp 
// 
// #include "interface.hpp" 
// 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    interface object(interface::create(true)); 

    if (object.test()) 
    { 
     // blah 
    } 
    else 
    { 
    } 
    return 0; 
} 

任何幫助,將不勝感激,我試圖隱藏的interface用戶interface::bodyspecific_body實現,如果這不是從我的問題很明顯。

回答

0

那麼的顯式實例添加模板<>,我能夠通過使body公開聲明在界面中的「解決」這個問題。這在申報specific_body時解決了C2248錯誤。我也做了body的朋友可以到interface類,並增加了一個方法,將body結構:

static interface create(body *pbody) 
{ 
    return interface(pbody); 
} 

,因此如果有一種specific_body

0

你還沒有資格specific_body。嘗試

template<class T> 
friend class internal::specific_body; 

作爲您的朋友聲明。

+0

感謝實例之間的嵌套關係的specific_body可以創建一個interface建議,它不利於雖然 – Queueless 2009-10-16 18:26:58

+0

出於興趣,所有這一切開始工作,如果你刪除的命名空間'internal'即只是把'specific_body'在全局命名空間? – Troubadour 2009-10-16 23:00:17

0

嘗試使用類型名稱可能?我認爲我在Sutter中讀到typename將工作到一個未知範圍內的類,而類不會。

+0

我在哪裏可以使用typename? – Queueless 2009-10-16 18:30:44

+0

我想你把它放在後或朋友 – messenger 2009-10-16 18:38:04

0

除了由遊吟詩人提到的不合格specific_body,specific_body <> ::試驗的true_struct和false_struct您專業化的嘗試似乎不正確。你必須專門的全班。

要解決該問題,我只需在公開區域聲明正文。另外聲明specific_body是interface :: body的朋友也沒有幫助。

+0

之前,我不知道爲什麼縮絨專業的'specific_body'類會在這種情況下,無所謂。 我在我的代碼申報身體公衆一個情況下幫助,但我已經在'specfic_body'需要訪問的'interface'太私有構造另一種情況;所以我想解決朋友訪問問題,或者重新構造代碼,以達到我可以從身體類固有的同一目標。 – Queueless 2009-10-16 18:45:03

+0

完全專業化無法使其符合C++標準。如果你沒有得到那部分的任何錯誤,你的編譯器可能會支持它作爲擴展,我不知道。但GCC拒絕它。只是說... – sellibitze 2009-10-16 18:55:37

+0

你在這裏看到的不符合要求是什麼?只專注於模板類的成員functon而不專門研究整個類在C++中是完全合法的。非正式地講,類模板的每個成員函數本身都是一個獨立的模板,可以獨立地進行專門化。這是一個很少使用的功能,但它在那裏。 14.7.3/16包含了這種專業化的例子。 – AnT 2009-10-18 08:43:02

1

您需要在模板測試方法

template<> // add this line 
bool specific_body<true_struct>::test() const 
{ 
    return true; 
} 
+0

是的,我忘了在我的例子中將這些行添加到測試方法的專業化中,但他們沒有幫助。感謝您的輸入。 – Queueless 2009-10-19 11:24:57

+0

檢查你的例子中是否沒有遺漏某些東西。修復它使用gcc 4.4.1編譯的行,並且正常工作。 – 2009-10-19 14:27:56

+0

好吧,他們似乎沒有與微軟的編譯器有所作爲,所以它看起來像是一個編譯器一致性問題。感謝您的意見。 – Queueless 2009-10-23 17:12:09