Using template template parameter on function call

↘锁芯ラ 提交于 2019-12-12 04:23:36

问题


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...


回答1:


Try the following:

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

It compiles at: http://ideone.com/tEWR5




回答2:


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


来源:https://stackoverflow.com/questions/11955859/using-template-template-parameter-on-function-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!