2017-09-24 26 views
0

這裏的目標是簡單得到a,b,c而不是他們的實際值。該設置是「很簡單」:防止意外的宏重新擴展與提升?

#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) 

所以我很期待在這一點上我有什麼:一個新的序列與(std::string("a"))等:

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

思考我這樣很聰明並以某些明確的字符串取得我的值,現在我定義「真實」代碼所需的實際值。

// 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 

而終於,讓打印出來,以確保它們不展開:

// 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); 
} 

不過好像外星人確實接管:

Humans: 
1. 123 
2. 456 
3. 789 

鑑於他們應該是std::string("a") ......真正的價值是如何回到那裏的?我認爲std::string構造函數中的("a")可能會產生問題,但似乎並不如此(BOOST_PP_STRINGIZE結果相同)。有什麼建議麼?

回答

1

宏確實擴展到代碼令牌

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

現在,當你插入代碼的令牌加入到GOTTA_PRINT_EM_ALL宏,你

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

完全果然打印

Humans: 
1. 123 
2. 456 
3. 789 

爲了得到「代碼令牌」 你需要stringize他們還有:

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

印刷

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

看到它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); 
} 
+0

我現在知道這是不是你想要什麼問。我會在這裏稍微留下這個「答案」,這樣你就可以澄清問題。我現在明白了,但並不十分清楚。創建一個不包含任何解釋的_self-contained_示例程序。 – sehe

+0

使用鏈接重複問題的答案:http://coliru.stacked-crooked.com/a/5405ce9f8218092f – sehe

+0

嗨@sehe感謝您解釋它並將我鏈接到我無法找到的問題。這一切現在變得更有意義了,我想我並沒有真正意識到引號在使用之前會被轉義 – sjm324