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)
....
expands a pattern to its left; in this case the pattern is the expression((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.这篇关于如何扩展对可变参数模板基类的调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何扩展对可变参数模板基类的调用?
基础教程推荐
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 从 std::cin 读取密码 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- Windows Media Foundation 录制音频 2021-01-01