0

The goal here is to simply get a, b, c out instead of their actual values. The setup is "simple enough":

#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <iostream>

// Define "invalid" sequence first
#define SEQ (a)(b)(c)

// Try to create "final" value with `std::string("elem")`
// Brought in for explicit `std::string`, but no dice
#define MAKE_XSTRING(x) MAKE_STRING(x)
#define MAKE_STRING(x)  std::string(#x)

// oh, the humanity!             vvvvvvvvvvvv or BOOST_PP_STRINGIZE
#define HUMANIZE(r, data, elem) (MAKE_XSTRING(elem))
#define SEQ_HUMAN BOOST_PP_SEQ_FOR_EACH(HUMANIZE,,SEQ)

So what I'm expecting at this point is what I have: a new sequence with (std::string("a")) etc:

// confirmation:     vvvvvvvvvvvvvvvv
// warning: Humans: (std::string("a")) (std::string("b")) (std::string("c"))
#pragma message "Humans: " BOOST_PP_STRINGIZE(SEQ_HUMAN)

Thinking I'm so very clever and have gotten my values sorted out in some explicit strings, now I define the actual values for what the "real" code needs.

// Now that we have the "final" values, actually define the real values
// in real code, it's some lengthy nested namespaces (inconvenient to type)
#define a 123
#define b 456
#define c 789

And at long last, lets print them to make sure they aren't expanded:

// Let there be printing!
#define GOTTA_PRINT_EM_ALL(r,data,i,elem) << ((i)+1) << ". " << elem << std::endl

int main(int argc, const char **argv) {
    std::cout << "Humans: " << std::endl
        BOOST_PP_SEQ_FOR_EACH_I(GOTTA_PRINT_EM_ALL,,SEQ_HUMAN);
}

But it seems the aliens did indeed take over:

Humans:
1. 123
2. 456
3. 789

Given that they're supposed to be std::string("a")...how the heck are the real values getting back in there?! I thought maybe the ("a") from the std::string constructor was creating issues, but it doesn't seem so (BOOST_PP_STRINGIZE results in same behavior). Any suggestions?

svenevs
  • 833
  • 9
  • 24

1 Answers1

1

The macro indeed expands into code tokens:

test.cpp|24 col 1| note: #pragma message: Humans: (std::string("123")) (std::string("456")) (std::string("789"))

Now when you insert the code tokens into your GOTTA_PRINT_EM_ALL macro, you get

<< ((0)+1) << ". " << std::string(\"123\") << std::endl << ((1)+1) << ". " << std::string(\"456\") << std::endl << ((2)+1) << ".  << std::string(\"789\")" << std::endl

Completely expectedly printing

Humans: 
1. 123
2. 456
3. 789

To get the "code tokens" you need to stringize them as well:

// Let there be printing!
#define GOTTA_PRINT_EM_ALL(r,data,i,elem) << ((i)+1) << ". " << BOOST_PP_STRINGIZE(elem) << std::endl

Printing

Humans: 
1. std::string("123")
2. std::string("456")
3. std::string("789")

See it Live On Coliru

#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <iostream>
#include <string>

#define a 123
#define b 456
#define c 789
#define SEQ (a)(b)(c)

// Try to create "final" value with `std::string("elem")`
// Brought in for explicit `std::string`, but no dice
#define MAKE_STRING(x)  std::string(#x)
#define MAKE_XSTRING(x) MAKE_STRING(x)

#define HUMANIZE(r, data, elem) (MAKE_XSTRING(elem))
#define SEQ_HUMAN BOOST_PP_SEQ_FOR_EACH(HUMANIZE,,SEQ)

// Let there be printing!
#define GOTTA_PRINT_EM_ALL(r,data,i,elem) << ((i)+1) << ". " << BOOST_PP_STRINGIZE(elem) << std::endl

int main() {
    std::cout << "Humans: " << std::endl
        BOOST_PP_SEQ_FOR_EACH_I(GOTTA_PRINT_EM_ALL,,SEQ_HUMAN);
}
sehe
  • 374,641
  • 47
  • 450
  • 633
  • I realize now this is not what you wanted to ask. I'll leave this "answer" up here a bit so you can CLARIFY the question. I get it now, but it's not at all very clear. Create a _self-contained_ sample program that doesn't leave anything to interpretation. – sehe Sep 24 '17 at 14:45
  • Using the answer from the linked duplicate question: http://coliru.stacked-crooked.com/a/5405ce9f8218092f – sehe Sep 24 '17 at 14:48
  • Hi @sehe thanks for explaining it and linking me to the question I was unable to find. This all makes a lot more sense now, I guess I wasn't really realizing that the quotes are escaped until used – svenevs Sep 24 '17 at 23:34