如何扩展对可变模板基类的调用? [英] How can I expand call to variadic template base classes?

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

问题描述

我有一组非正交的策略,所有这些策略都实现了一个通用命名方法,这些策略添加了安全检查。
我希望用户能够组合策略以允许更复杂的验证,而无需手动为每个组合案例创建策略。
我的方法是创建一个新的策略类来组合其他方法。

I have a set of non-orthogonal policies, all of them implementing a common named method, the policies add safety checks. I want users to be able to combine the policies to allow more complex validation without creating policies for each combination case by hand. My approach is creating a new policy class to combine others.

下面的简化示例显示了C作为组合类,这里的方法id是组合的。预期的结果是,当在C上调用id时,顺序调用每个基类的id。

The simplified example below shows C as the combining class, here the method id is combined. The expected result is, when calling id on C, to sequentially call the id of each base class.

#include <iostream>
using namespace std;

struct A 
{
    void id() { cout << "A ";}
};

struct B 
{
    void id() { cout << "B ";}
};

template<class A, class... As>
struct C : public A, public As... 
{
    void id()
    {
         A::id();
         As...::id(); // This line does not work, it is illustrative.
    }
};

int main()
{
    C<A, B> c;
    c.id();

    //expected: result A B 
}

是:可以扩展As ...不知怎么做,而不使用递归方法,只是使用...运算符?

The question is: Is it possible to expand As... somehow to do this without using a recursive approach, just using the ... operator?

推荐答案

当然。你需要一个允许包扩展的上下文 - 一个简单的初始化列表,它也有利于保证从左到右的评估:

Sure. You need a context that permits pack expansion - a simple one is a braced initializer list, which also has the benefit of guaranteeing left-to-right evaluation:

using expander = int[];
(void) expander { 0, ((void) As::id(), 0)... };




  • ... 将模式向左扩展;在这种情况下,模式是表达式((void)As :: id(),0)

    表达式中的是逗号运算符,用于计算第一个操作数, ,然后评估第二个操作数,并返回结果。

    The , in the expression is the comma operator, which evaluates the first operand, discards the result, then evaluates the second operand, and returns the result.

    演示

    在C ++ 17(如果我们幸运) ,则 C :: id 的整个主体可以替换为一个二进制折叠表达式(A :: id(),...,(void)As :: id()); 隐藏

    In C++17 (if we are lucky), the entire body of C::id can be replaced with a binary fold expression: (A::id(), ... , (void) As::id()); Demo.

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

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