In C , it's often desirable to iterate through variadic template arguments and perform a specific operation, such as calling a function. This can be achieved using either:
(f(args), ...);
However, if the called function potentially returns an object with an overloaded comma operator, you should use:
((void)f(args), ...);
A common approach is to leverage list-initialization and perform the expansion within it:
{ print(Args)... }
Since print() returns void, you can workaround the issue by returning int:
{ (print(Args), 0)... }
To ensure this works with any number of arguments, you can make the pack always have at least one element:
{ 0, (print(Args), 0)... }
You can encapsulate this pattern into a reusable macro:
namespace so { using expand_type = int[]; } #define SO_EXPAND_SIDE_EFFECTS(PATTERN) ::so::expand_type{ 0, ((PATTERN), 0)... }
To handle overloaded comma operators, you can modify the macro:
#define SO_EXPAND_SIDE_EFFECTS(PATTERN) \ ::so::expand_type{ 0, ((PATTERN), void(), 0)... }
If you're concerned about unnecessary memory allocation, you can define a custom type that supports list-initialization but doesn't store data:
namespace so { struct expand_type { template <typename... T> expand_type(T&&...) {} }; }
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3