变量模板基类调用转发 [英] Variadic template base class call forwarding

查看:84
本文介绍了变量模板基类调用转发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在11之前的C ++我有这样的:

In pre-11 C++ I had something like this:

template<class T,class U,class V>
struct Foo : T,U,V {

  bool init() {

    if(!T::init() || !U::init() || !V::init())
      return false;

    // do local init and return true/false
  }
};

我想将其转换为C ++ 11可变语法,长度参数列表。我理解解包模板arg列表使用递归的概念,但我只是看不到获得语法正确。这里是我试过的:

I'd like to convert this to C++11 variadic syntax to get the benefit of the flexible length argument list. I understand the concept of unpacking the template arg list using recursion but I just can't seen to get the syntax right. Here's what I've tried:

template<typename... Features>
struct Foo : Features... {

  template<typename F,typename... G>
  bool recinit(F& arg,G&& ...args) {

    if(!F::init())
      return false;

    return recinit<F,G...>(args...);
  }

  bool init() {
    // how to call recinit() from here?
  }
};



我更喜欢调用基类init()函数的顺序是左对齐

I would prefer the order of the calls to the base class init() functions to be left-to-right but it's not critical.

推荐答案

这应该可以工作:

template<typename F, typename... T>
    struct recinit;

template<typename F>
    struct recinit<F> {
        static bool tinit(F *) {
            return true;
        }
    };
template<typename F, typename T, typename... G>
    struct recinit<F, T, G...> {
        static bool tinit(F *ptr)  {
            if (!ptr->T::init())
                return false;
            return recinit<F, G...>::tinit(ptr);
        }
    };

template<typename... Features>
struct Foo : Features... {

    bool init() {
        bool res = recinit<Foo, Features...>::tinit(this);
        //use res wisely
    }
};

您的问题是,您不能编写函数的部分特化,只能编写类/结构。辅助结构必须在 Foo 之外,否则它将从包含的结构中获取模板参数,这将是坏的。

Your problem is that you cannot write partial specializations of functions, only of classes/structs. And the auxiliary struct has to be outside of Foo or else it will get the template arguments from the enclosing struct, and that would be bad.

你不说,但我假设 init 是一个非静态成员函数。如果是这样, args 参数没有意义:所有的都应该 this !所以只是过去这一次,避免在论据中的包。我尝试将作为 void * 传递,但这可能很麻烦,所以我只是添加了一个额外的模板参数 recinit 将会是 Foo

You don't say but I'm assuming that init is a non-static member function. If that is the case, the args arguments make little sense: all of them should be this! So just past this once and avoid the pack in the arguments. I tried passing this as a void* but that may be troublesome, so I just added an additional template argument to recinit that will be Foo.

时间你做一个递归步骤记得删除一个参数。

And also, each time you do one recursive step remember to remove one parameter.

这篇关于变量模板基类调用转发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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