Em C , muitas vezes é desejável iterar através de argumentos de modelo variados e executar uma operação específica, como chamar uma função. Isso pode ser conseguido usando:
(f(args), ...);
No entanto, se a função chamada retornar potencialmente um objeto com um operador de vírgula sobrecarregado, você deve usar:
((void)f(args), ...);
Uma abordagem comum é aproveitar a inicialização da lista e realizar a expansão dentro dela:
{ print(Args)... }
Como print() retorna void, você pode solucionar o problema retornando int:
{ (print(Args), 0)... }
Para garantir que isso funcione com qualquer número de argumentos, você pode fazer com que o pacote sempre tenha pelo menos um elemento:
{ 0, (print(Args), 0)... }
Você pode encapsular esse padrão em uma macro reutilizável:
namespace so { using expand_type = int[]; } #define SO_EXPAND_SIDE_EFFECTS(PATTERN) ::so::expand_type{ 0, ((PATTERN), 0)... }
Para lidar com operadores de vírgula sobrecarregados, você pode modificar a macro:
#define SO_EXPAND_SIDE_EFFECTS(PATTERN) \ ::so::expand_type{ 0, ((PATTERN), void(), 0)... }
Se estiver preocupado com a alocação desnecessária de memória, você pode definir um tipo personalizado que suporte lista- inicialização, mas não armazena dados:
namespace so { struct expand_type { template <typename... T> expand_type(T&&...) {} }; }
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3