Pergunta

Estou tentando fazer algum tipo de macro "sobrecarga", para que a macro (algo) seja expandida de maneira diferente da macro (algo, outra pessoa).

Usando um trecho que eu obtive de aqui (Não tenho certeza se é 100% portátil) e algumas funções da biblioteca Boost PP, pude fazê -lo funcionar: D

//THESE TWO COUNT THE NUMBER OF ARGUMENTS
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)

//THIS ONE RETURNS THE PARAMETER AT POSITION _i FROM A LIST OF __VA_ARGS__
#define VA_ARG(_i, ...) BOOST_PP_ARRAY_ELEM(_i, (VA_NARGS(__VA_ARGS__), (__VA_ARGS__)))

//AND THIS ONE IS THE 'OVERLOADED' MACRO ;)
#define TEST(...) BOOST_PP_IF(BOOST_PP_EQUAL(1, VA_NARGS(__VA_ARGS__)), function_A(VA_ARG(0, __VA_ARGS__)), \ //1 parameter
                  BOOST_PP_IF(BOOST_PP_EQUAL(2, VA_NARGS(__VA_ARGS__)), function_B(VA_ARG(0, __VA_ARGS__) + VA_ARG(1, __VA_ARGS__)), \ //2 parameters
                  BOOST_PP_IF(BOOST_PP_EQUAL(3, VA_NARGS(__VA_ARGS__)), function_C(VA_ARG(1, __VA_ARGS__) + VA_ARG(2, __VA_ARGS__)), BOOST_PP_EMPTY())) // 3 parameters and so on ...

So       TEST(a) = function_A(a)
      TEST(a, b) = function_B(a + b)
   TEST(a, b, c) = function_C(b + c)

Agora ainda estou perdendo duas outras coisas que quero fazer:

  1. (Este eu realmente não me importo se nunca o resolver) Acredito que uma macro possa ser escrita que, ao adotar o número de 'variantes' e sua 'saída' correspondente, gera um código semelhante ao acima. Algo como modelo (3, function_a (...), function_b (...), function_c (...)) para gerar o exemplo acima.

  2. O que acontece quando o teste () é chamado sem argumentos? Bem, Va_Nargs se expande para 1. Mas o primeiro argumento é "" (nada). Estou tentando encontrar uma maneira de detectar argumentos 'zero' em __VA_ARGS__ ou diferenciar entre um argumento 'nulo' e um real, a fim de estender a função 'sobrecarga' para reagir a essa situação. Alguma ideia?

Foi útil?

Solução

Para responder à sua pergunta 2 primeiro. Sim, com macros variádicos, também é possível detectar uma lista de argumentos vazia. A explicação é um pouco longa, eu escrevi aqui. Deve ser relativamente fácil combinar essa abordagem com as macros do Boost que você está usando.

Para sua pergunta 1, sim, isso também é possível. O Boost tem algumas macros do iterador que se aproximam disso, eu acho, mas parecem um pouco assustadoras de usar. Se eu entendi corretamente, você tem que usar algo como listas aninhadas (a, (b, (c,d))), não é muito conveniente.

(Eu escrevi um conjunto de macros que podem conseguir isso mais diretamente, mas infelizmente o pacote ainda não está pronto para ser lançado. Entre em contato comigo em particular se você estiver verdade interessado nisso.)

Editar: o P99 O pacote é publicado nesse meio tempo e contém muitas coisas sobre o macro "sobrecarga" e digite macros genéricos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top