How can I expand call to variadic template base classes?

前端 未结 1 930
慢半拍i
慢半拍i 2020-11-27 18:57

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 a

相关标签:
1条回答
  • 2020-11-27 19:29

    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)... };
    
    • ... 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.

    • The (void) cast on As::id() exists to guard against overloaded operator,, and can be omitted if you are sure that none of the As::id() calls will return something that overloads the comma operator.
    • 0 on the right hand side of the comma operator is because expander is an array of ints, so the whole expression (which is used to initialize an element of the array) must evaluate to an int.
    • The first 0 ensures that we don't attempt to create an illegal 0-sized array when As is an empty pack.

    Demo.


    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.

    0 讨论(0)
提交回复
热议问题