我有一個模板函數的類:代理模式可以適應模板功能嗎?
了foo.h:
class Foo {
public:
int some_function();
bool some_other_function(int a, const Bar& b) const;
template<typename T>
int some_template_function(const T& arg);
};
template<typename T>
int Foo::some_template_function(const T& arg){
/*...generic implementation...*/
}
現在我走到一個地步,我希望能夠通過代理類來訪問富,如在Proxy design pattern中那樣。
直觀地說,我想重構如下(下面的代碼是不正確的,但它表達了我的 「理想化」 API):
FooInterface.h:
class FooInterface {
public:
virtual int some_function()=0;
virtual bool some_other_function(int a, const Bar& b) const=0;
template<typename T>
virtual int some_template_function(const T& arg)=0;
};
FooImpl.h:
#include "FooInterface.h"
/** Implementation of the original Foo class **/
class FooImpl : public FooInterface {
public:
int some_function();
bool some_other_function(int a, const Bar& b) const;
template<typename T>
int some_template_function(const T& arg);
};
template<typename T>
int FooImpl::some_template_function(const T& arg){
/*...generic implementation...*/
}
FooProxy.h:
#include "FooInterface.h"
class FooProxy : public FooInterface{
protected:
FooInterface* m_ptrImpl; // initialized somewhere with a FooImpl*; unimportant in the context of this question
public:
int some_function()
{ return m_ptrImpl->some_function(); }
bool some_other_function(int a, const Bar& b) const
{ return m_ptrImpl->some_other_function(a,b); }
template<typename T>
int some_template_function(const T& arg)
{ return m_ptrImpl->some_template_function(arg); }
};
但這個代碼悲慘的失敗了。
首先,FooImpl
無法編譯,因爲類模板函數不能是虛擬的。
更重要的是,即使我玩弄了some_template_function
的定義,即使我將它重新定位到具體的課程或其他陪審團索具,它仍然會對整個首先是代理類,因爲模板代碼需要在標題中定義幷包含在內。這將迫使FooProxy.h
包括FooImpl.h
和FooImpl.h
需要所有的實施細節和文件,包括實施some_template_function
必需的。因此,如果我使用代理模式來模糊實現細節,將自己與具體實現相隔離,並避免不必要的文件包含,那麼我的運氣不好。
有沒有辦法將代理模式或其某些變體應用於具有模板函數的類?或者在C++中這是不可能的?
語境:此刻,我想提供一組具有預先存在的類,內置日誌機制代理訪問。我爲此日誌使用的唯一API使用可變參數模板,因此無法預測將要使用的參數組合。我希望使用代理的實現和客戶端之間的分離儘可能地乾淨,並且我需要儘量減少從客戶端到實現的依賴關係,但我確實需要它們寫入相同的日誌。
但是,我對這個問題感興趣超出了我的眼前的問題。令我感到困惑的是,模板將這樣的洞捅入了主要的設計模式,並且我沒有發現這個問題在任何地方都能解決。
是的,如果你在編譯時知道你想要什麼,有一種方法。這個味道有點像[xy問題](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem),所以你可以詳細說明你正在嘗試做什麼如何?如果無法預測可能需要實例化模板的所有類型,則無法隱藏模板實現,否則可以顯式實例化模板以獲取所需的類型。 – mars
@mars:夠公平的;我試圖將問題簡化爲最簡單的形式。我會在某些情況下進行編輯。 – Ziv
對不起,但我沒有想出如何使用模板方法編寫代理的解決方案,它不會將原始模板代碼放在標題中(預編譯標題有幫助嗎?)。除了你的問題之外,編寫一個代理'template class proxy {Implementation * m_ptrImpl; ...};'只要模板方法可用或顯式實例化,就可以以你期望的方式工作。 [如何在C++中實現虛擬模板功能](http://stackoverflow.com/questions/5871722/how-to-achieve-virtual-template-function-in-c)可能很有趣,暗示訪問者模式。 –
mars