多个可变模板化委托系统

时间:2013-03-05 11:28:45

标签: c++ templates c++11 delegates metaprogramming

所以,我最近使用c ++ 11的可变参数模板构建了一个委托系统,它就像一个魅力。

然而,在系统中我已经在创建时建立了函数的参数(正如我所愿),但是现在我也希望能够在调用时传递一些(变量)参数。时间。为了实现这一点,我去了我的代码,但是我正在解决问题;

error: parameter packs must be at the end of the parameter list
sorry, unimplemented: cannot expand ‘Arguments ...’ into a fixed-length argument list
error: type/value mismatch at argument 1 in template parameter list for ‘template<<declaration error>, class ... Params> class FunctionDelegate’

......还有更多内容,所以这里有一个产生问题的片段;

template<typename... Params> 
class Runnable
{
    public:
        virtual void invoke(tuple<Params...> params) = 0;
        virtual ~Runnable() 
        {
        }
};

这是我的两个代理(FunctionDelegate和ObjectDelegate)的父类。这曾经是一个没有模板的类(因为invoke没有接受任何参数),但是因为我有一个可变参数模板列表,所以我必须修改我的子类(显然),我刚刚添加了另一个可变参数模板给他们;

template<typename... Arguments, typename... Params>
class FunctionDelegate : public Runnable<Params...>
{
    public:
        typedef void (*FunctionType)(Arguments..., Params...);

        FunctionDelegate(FunctionType function, tuple<Arguments...> args)
            : function(function), args(args)
        {
        }

        void invoke(tuple<Params...> params) 
        {
            callFunction(typename gens<sizeof...(Arguments)>::type(), params, typename gens<sizeof...(Params)>::type());
        }
    private:
        template<int... S, int... R>
        void callFunction(seq<S...>, tuple<Params...> params, seq<R...>)
        {
            function(get<S>(args)..., get<R>(params)...);
        }
    private:
        FunctionType function;
        tuple<Arguments...> args;
};

然而,这似乎不被允许,至少这是我怀疑的,所以;

  1. 是否允许有两个可变参数模板列表?
  2. 有没有办法,我可以提示编译器,哪个列表是哪个? (即构造函数中使用的那些转到Arguments,其余的转到Params)。
  3. 如果根本没有办法做到这一点(使用两个可变参数模板列表),是不是可以在同一个可变参数列表中使用一个参数和参数,然后简单地使用构造函数的参数拆分它?
  4. 还有其他办法可以实现我的目标吗? (除了使用普通的旧的,非类型检查的可变参数传递)。
  5. 欢迎任何帮助或见解。

2 个答案:

答案 0 :(得分:5)

不,你不能使用这样的代码。您可以使用以下示例

template<typename... Params>
class FunctionDelegate;

template<typename Arguments, typename Params>
class FunctionDelegate;
正如Xeo所暗示的那样。

template<typename... Arguments, typename... Params>
class FunctionDelegate<tuple<Arguments...>, tuple<Params...>> : 
public Runnable<Params...> { // };

答案 1 :(得分:4)

关于您的前两个问题(答案为“”和“”),C ++ 11标准的第14.1 / 11段指定:

  

如果类模板或别名模板的模板参数具有默认模板参数,则每个模板参数都是后续的   template-parameter要么提供默认的template-argument,要么是模板参数   包。 如果主类模板或别名模板的模板参数是模板参数包,   它应该是最后一个模板参数。函数模板的模板参数包不得   后跟另一个模板参数,除非可以推导出该模板参数或具有默认值   论证(14.8.2)。 [例如:

template<class T1 = int, class T2> class B; // error
// U cannot be deduced or specified
template<class... T, class... U> void f() { }
template<class... T, class U> void g() { }
  

-end example]

您的示例明显违反粗体句子,该句子禁止在(主)类模板上包含多个模板参数包。