0

实际上,所有答案都很好,而且内容丰富,但它们并没有解决我的特定问题。我不认为这是回答的非常乐于助人的人的错,而是我的问题措辞很糟糕。因此,我决定在这里发布一个带有更多相关代码示例的全新问题:Mixing Command pattern, Factory pattern and templates all together ...。如果有人愿意看...

现在原来的问题:

我不认为有可能做我想做的,但我问,以防万一......

我有一系列我想通过工厂创建的模板类。我使用工厂的原因是工厂有一些数据成员用于初始化通过该工厂创建的每个类。

例如,让我们考虑这个类:

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 operator()(P1 p1, P2 p2, P3 p3, P4 p4)”行产生以下错误:

错误 C2065:“P1”:未声明的标识符

因为像“DoSomething”这样的类只有一个声明(DoSomething 将始终使用 < int, float >),我认为我可以使用模板参数推导,并最终得到如下语法:

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*/);

但这是多余的,不是很优雅......

4

2 回答 2

1

首先,定义如下

class DoSomething : public UndoableCommand< int, float >

DoSomething是一种类型,而不是模板,因此您不能将它与这样的功能一起使用。

让我们考虑一下,您定义DoSomething

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

然后,我注意到,你的函数有 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);
}
于 2012-08-14T16:04:53.523 回答
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

于 2012-08-14T15:46:26.690 回答