在函数调用中使用模板模板参数 [英] Using template template parameter on function call

查看:135
本文介绍了在函数调用中使用模板模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


其实,所有的答案都很好,信息丰富,但他们不解决我的特定问题。我不认为这是非常有帮助的人的错误,但回答,而是,我严重地说我的问题。因此,我决定在这里发布一个全新的问题和更多相关的代码示例:混合命令模式,出厂模式和模板在一起... 。如果任何人关心看... ...



现在的原始问题:



我不认为可以做我想要,但我问,只是为了情况....



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



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

  class DoSomething:public UndoableCommand< int,float> 

我试图创建一个命令工厂,所以它可以创建类似上面的类, (非模板)CommandFactory中,我定义了以下方法:

  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':undeclared identifier


因为像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 * /) 

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

解决方案

首先,像这里定义

  class DoSomething:public UndoableCommand< int,float> 

DoSomething 是一种类型,



让我们考虑,你定义 DoSomething like

 模板< 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);
}


Actually, all the answers are nice, and informative but they don't solve my particular problem. I don't think that's the fault of the very helpful people who replied but instead, I badly phrased my question. Therefore I decided to post a completely new question with more relevant code examples here : Mixing Command pattern, Factory pattern and templates all together ... . If anyone cares to look ...

Now the original question :

I dont think it's possible to do what I want but I ask, just in case....

I have a familly of template classes I'd like to create through a factory. The reason why I use a factory is because the factory has some data members which are used for initializing every class created through that factory.

For example, let's consider this class :

class DoSomething : public UndoableCommand< int, float >

I tried to create a command factory, so it can create classes like the one above, and take care of their initialization, lifetime etc ...

In my (non-template) CommandFactory, I defined the following method :

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);
//...
}

However, this doesn't compile. The line "void operator()(P1 p1, P2 p2, P3 p3, P4 p4)" produces the following error :

error C2065: 'P1' : undeclared identifier

Because classes like "DoSomething" have only one declaration (DoSomething will always use < int, float >), I thought that I could use template argument deduction, and end up with a syntax like :

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

Is it possible at all ? If so, what's the appropriate syntax ?

I guess I could always define my factory method like :

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);
//...
}

and then call

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

but that is redundant and not very elegant...

解决方案

First of all, defined like here

class DoSomething : public UndoableCommand< int, float >

DoSomething is a type, not a template, so you cannot use it with such a function.

Lets consider, you defined DoSomething like

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

Then, I noted, that your function has 4 params, but your DoSomething has only 2. If you really want use variable count of parameters, you should use variadic templates.

So, your function should look like that:

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

And you can use it the following way:

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

这篇关于在函数调用中使用模板模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆