2

所以,我最近使用 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. 还有其他方法可以实现我正在尝试的吗?(除了使用普通的旧的、非类型检查的可变参数传递)。

欢迎任何帮助或见解。

4

2 回答 2

5

No, you cannot use such code. You can use following for example

template<typename... Params>
class FunctionDelegate;

or

template<typename Arguments, typename Params>
class FunctionDelegate;

as Xeo suggests.

template<typename... Arguments, typename... Params>
class FunctionDelegate<tuple<Arguments...>, tuple<Params...>> : 
public Runnable<Params...> { // };
于 2013-03-05T11:38:21.843 回答
4

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

如果类模板或别名模板的模板参数具有默认模板参数,则每个后续模板参数应提供默认模板参数或模板参数包。如果主类模板或别名模板的模板参数是模板参数包,它应该是最后一个模板参数。函数模板的模板形参包后面不应跟随另一个模板形参,除非该模板形参可以推导出来或具有默认实参(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() { }

—结束示例]

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

于 2013-03-05T11:35:02.030 回答