Question

I'd like to write some c++ macro code to convert:

#define FRUITS Apple Banana Plum
EXPAND(FRUITS)

into:

void eat(Apple& instanceApple);
void eat(Banana& instanceBanana);
void eat(Plum& instancePlum);

Is it possible to write an EXPAND() function to accomplish my goal?

I realize this doesn't look like good programming practice, but I have to link to a 3rd-party library with a specific interface, and the ability to do this will allow me to avoid large repetitive code blocks within my own code.

EDIT: changed my toy example slightly.

Was it helpful?

Solution

I'm not saying this does much for readability, but it does what you want using Boost.Preprocessor:

#define DECLARE_VAR(r, data, type) type BOOST_PP_CAT(instance,type);
#define EXPAND(seq) BOOST_PP_SEQ_FOR_EACH(DECLARE_VAR,,seq)

Now you can define your list of fruits as follows:

#define FRUITS (Apple)(Banana)(Plum)

And then you can use EXPAND(FRUITS) to generate the variable declarations. For a full example, see here.

Per request, the same technique used to print one fruit per line:

#include <iostream>
#include <boost/preprocessor.hpp>

#define PER_LINE(r, data, type) BOOST_PP_STRINGIZE(type) "\n"
#define EXPAND(seq) BOOST_PP_SEQ_FOR_EACH(PER_LINE,,seq)

#define FRUITS (Apple)(Banana)(Plum)

int main() {
    std::cout << EXPAND(FRUITS);
}

OTHER TIPS

Don't have time to explain, but I just made this:

struct A
{
  int i;
  A(){i=1;}
  void quack() {std::cout << "A" << i << std::endl;}
};

struct B
{
  int i;
  B(){i=2;}
  void quack() {std::cout << "B" << i << std::endl;}
};
struct C
{
  int i;
  C(){i=3;}
  void quack() {std::cout << "C" << i << std::endl;}
};

#include <tuple>
std::tuple<A,B,C> tupl;


struct quacker
{
  template <typename T>
void operator()(T& t)
{
  t.quack();
}
};

template <typename Q,std::size_t index, typename... Ts>
typename std::enable_if<
index < sizeof...(Ts) >::type foo_helper(Q q,std::tuple<Ts...>& ts)
{
  q(std::get<index>(ts));
  foo_helper<Q,index+1,Ts...>(q,ts);
}
template <typename Q,std::size_t index, typename... Ts>
typename std::enable_if<
index >= sizeof...(Ts) >::type foo_helper(Q q,std::tuple<Ts...>& ts)
{

}

template <typename Q, typename... Ts>
void foo(Q q,std::tuple<Ts...> ts)
{
  foo_helper<Q,0,Ts...>(q,ts);
}





int main(int argc,char** argv)
{

  foo(quacker(),tupl);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top