2012-08-14 127 views
0

其實,所有的答案都很好,而且內容翔實,但它們不能解決我的特殊問題。我不認爲這是回答非常有幫助的人的錯,而是我嚴厲地解釋了我的問題。因此,我決定在這裏發佈一個全新的問題,其中包含更多相關的代碼示例:Mixing Command pattern, Factory pattern and templates all together ...。如果有人關心一下......在函數調用中使用模板模板參數

現在,原題:

我不認爲這是可以做到我想要什麼,但我要問,以防萬一....

我有一個familly我希望通過工廠創建模板類。 我使用工廠的原因是工廠有一些數據成員,用於初始化通過該工廠創建的每個類。

例如,讓我們考慮這個類:

class DoSomething : public UndoableCommand< int, float > 

我試圖創建一個命令工廠,所以它可以創建類像上面的,並照顧他們的初始化,壽命等等

在我的(非模板)的CommandFactory,我定義了以下方法:

template < template <typename P1, typename P2, typename P3, typename P4> class CommandType> 
void createCommand(P1 p1, P2 p2, P3 p3, P4 p4) 
{ 
UndoableCommand* cmdPtr; 
cmdPtr=new CommandType(P1 p1, P2 p2, P3 p3, P4 p4); 
//... 
} 

然而,這並不編譯。行 「void運算符()(P1 P1,P2 P2,P3 P3,P4 P4)」 產生以下錯誤:

錯誤C2065:P1':未聲明的標識符

因爲類等「DoSomething的」只有一個聲明(DoSomething的總是會使用<整數,浮點>),我以爲我可以使用模板參數推導,並用語法落得像:

myCommandFactory.createCommand<DoSomething>(1 /*int*/, 1.0f /*float*/); 

是否有可能在所有?如果是這樣,什麼是適當的語法?

我想我隨時可以定義我的工廠方法,如:

template <class CommandType, typename P1, typename P2, typename P3, typename P4> 
void createCommand(P1 p1, P2 p2, P3 p3, P4 p4) 
{ 
UndoableCommand* cmdPtr; 
cmdPtr=new CommandType(P1 p1, P2 p2, P3 p3, P4 p4); 
//... 
} 

,然後調用

myCommandFactory.createCommand<DoSomething, int, float>(1 /*int*/, 1.0f /*float*/); 

但這是多餘的,不是很優雅......

+1

有沒有這樣的事,作爲一個'模板class',只有'類模板'。 – pmr 2012-08-14 16:12:52

回答

1

嘗試如下:

struct UndoableCommand { }; 

template < 
    template <typename P1, typename P2> class CommandType, 
    typename P1a, typename P2a 
     > 
void createCommand(P1a p1, P2a p2) 
{ 
    UndoableCommand *cmdPtr = new CommandType<P1a,P2a>(p1, p2); 
} 

template <typename P1, typename P2> class MyCommand : public UndoableCommand 
{ 
public: 
    MyCommand(P1, P2) { } 
}; 

int main() 
{ 
    createCommand<MyCommand>(1, 2.0); 
} 

它編譯於:http://ideone.com/tEWR5

+1

我將首先使用template-template參數,以便它可以用作'createCommand (args)',而不必指定參數的類型。 – 2012-08-14 15:51:08

+0

我更新了我的答案。 – 2012-08-14 16:02:44

+0

哇你們比我更深刻的模板undertsanding!基里爾,你的代碼似乎工作。我沒有嘗試實際調用create方法,因爲我有其他錯誤,但至少編譯了它。戴夫,你介意發展你的答案嗎? – Dinaiz 2012-08-14 16:03:40

1

首先,定義喜歡這裏

class DoSomething : public UndoableCommand< int, float > 

DoSomething是一個類型,而不是一個模板,所以你不能用這樣的功能使用。

讓我們考慮,你喜歡

template <typename T, typename V> 
struct DoSmth: public UndoableCommand { 
    DoSmth(T, V){} 
}; 

定義DoSomething然後,我注意到,你的函數有4個參數,可以,但你的DoSomething只有2.如果你真的想使用的參數變量數,你應該使用可變模板。

所以,你的函數應該看起來像:

struct Factory 
{ 
    template < template <typename...> class CommandType, typename... T> 
    void createCommand(T... args) 
    { 
     UndoableCommand* cmdPtr = new CommandType<T...>(args...); 
    } 
}; 

而且你可以用它的方式如下:

int main() 
{ 
    Factory f; 
    f.createCommand<DoSmth>(1, false); 
} 
+0

你是絕對正確的。你的例子就是我真正在代碼中做的事情,我只是簡化了它,並使其錯誤。我的錯。但是,我真的想有一個成員函數,而不是一個自由函數。沒有辦法,是嗎? – Dinaiz 2012-08-14 16:10:38

+0

@Dinaiz,你想讓'createCommand'成員函數?去做就對了!沒有任何問題,除了它應該_defined_(與_declared_相反)在頭文件中(不在'cpp'文件中) – Lol4t0 2012-08-14 16:13:03

+0

@Dinaiz,將'createCommand'移到'struct' – Lol4t0 2012-08-14 16:15:57