如何扩展对可变参数模板基类的调用?

德维奇诺

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

下面的简化示例将C作为组合类,此处将方法ID组合在一起。在C上调用id时,预期结果是依次调用每个基类的id。

#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 
}

问题是:是否可以通过仅使用...运算符以某种方式扩展为...而无需使用递归方法呢?

TC

当然。您需要一个允许扩展包的上下文-一个简单的上下文是一个大括号的初始化程序列表,它还具有保证从左到右求值的好处:

using expander = int[];
(void) expander { 0, ((void) As::id(), 0)... };
  • ...向左扩展模式;在这种情况下,模式就是表达式((void) As::id(), 0)

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

  • (void)上投As::id()的存在是为了防止过载operator,,并且可以省略,如果你确信没有任何的As::id()调用将返回一些重载逗号操作符。
  • 0逗号运算符右侧的是因为expander是的数组int,因此整个表达式(用于初始化数组的元素)必须求值为int
  • 第一个0确保当As空包时,我们不会尝试创建非法的0大小的数组

演示


在C ++ 17(如果我们幸运的话),整个身体C::id可以替换一个二进制倍的表达(A::id(), ... , (void) As::id()); 演示

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

可变参数模板包扩展

如何存储可变参数模板参数?

从派生的可变参数模板类中调用基本模板的虚拟方法

使用可变参数模板扩展

可变参数模板扩展中的函数调用顺序

不同的可变参数模板扩展

如何从双参数模板创建单参数模板以用作基类模板模板参数

可变参数模板函子调用

可变参数模板的多重继承:如何为每个基类调用函数?

从可变参数模板构造类

decltype()可变参数模板基类

如何:将C ++ 14模板函数扩展为可变参数模板,参数

SFINAE和可变参数模板类

基准可变参数模板函数调用

如何使用可变参数模板参数进行模板函数调用?

是否可以从可变参数模板调用多个基类构造函数?

如何在SWIG中包装可变参数模板类的可变参数模板成员函数?

如何扩展可变参数模板类

调用类内的函数的C ++ 11可变参数模板

可变参数模板类未完全扩展

可变参数模板类的可变参数模板

菊花链可变参数模板类

以可变参数类模板作为函数调用参数的函数模板参数推导

如何仅对父类可变参数模板参数启用嵌套类模板?

可变参数模板索引包扩展

可变参数模板类-可变参数成员函数

当可变参数模板类从模板参数继承时,在调用基类型的方法时扩展参数包

如何专门定义在可变参数模板类中定义的可变参数方法?

使用可变参数类模板的模板参数调用可变参数函数模板?