如何扩展对可变模板基类的调用? [英] How can I expand call to variadic template base classes?
问题描述
我有一组非正交的策略,所有这些策略都实现了一个通用命名方法,这些策略添加了安全检查。
我希望用户能够组合策略以允许更复杂的验证,而无需手动为每个组合案例创建策略。
我的方法是创建一个新的策略类来组合其他方法。
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屋!