微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – Variadic模板基类呼叫转发

在11 C之前我有这样的事情:
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列表的概念,但我无法看到正确的语法.这是我尝试过的:

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()函数调用顺序是从左到右,但它并不重要.

解决方法

这应该工作:
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之外,否则它将从封闭结构中获取模板参数,这将是不好的.

你没有说,但我假设init是一个非静态成员函数.如果是这种情况,args参数就没有意义了:所有这些都应该是这样的!所以只要过去一次就可以避免争论中的包装.我尝试将其作为void *传递但是这可能很麻烦,所以我只是添加一个额外的模板参数来重新定义将是Foo.

而且,每次执行一个递归步骤时,请记住删除一个参数.

原文地址:https://www.jb51.cc/c/111300.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐