所以,已经有一段时间了,因为我用C ++编写任何东西,现在我正在使用C ++ 11和宏进行项目。
我知道通过使用stringify运算符,我可以这样做:
#define TEXT(a) #a //expands to "a"
我应该如何使用预处理器来识别像+和*这样的标记来执行此操作:
#define TEXT(a)+ ??? //want to expand to "a+"
#define TEXT(a)* ??? //want to expand to "a*"
什么时候输入必须是那种语法?
我试过这样做:
#define + "+"
但当然它不起作用。如何让预处理器识别这些令牌?
注意: 这实际上是定义和使用正则表达式的小语言项目的一部分,其中生成的宏字符串将用于正则表达式。给出了语法,我们必须按原样使用它,而不对其进行任何更改。
例如
TEXT(a)+
用于制作正则表达式:std::regex("a+")
不改变TEXT(a)
扩展为" a"
答案 0 :(得分:2)
首先,
#define TEXT(a) #a
没有“转换为"a"
”。 a
只是参数的名称。宏扩展为包含调用的TEXT
的字符串。因此TEXT(42 + rand())
将扩展为"42 + rand()"
。请注意,如果将宏作为参数传递,则不会展开宏。 TEXT(EXIT_SUCCESS)
将扩展为"EXIT_SUCCESS"
,而不是"0"
。如果您想要完全展开,请添加一个额外的间接层,并将参数传递给TEXT
到另一个执行字符串化的宏TEXT_R
。
#define TEXT_R(STUFF) # STUFF
#define TEXT(STUFF) TEXT_R(STUFF)
其次,我不太清楚您对TEXT(a)+
和TEXT(a)*
的意思。您想要TEXT(foo)
扩展为"foo+"
吗?我认为在这种情况下最简单的解决方案是使用隐式字符串文字串联。
#define TEXT_PLUS(STUFF) # STUFF "+"
#define TEXT_STAR(STUFF) # STUFF "*"
或者,如果你想要完全扩展。
#define TEXT_R(STUFF) # STUFF
#define TEXT_PLUS(STUFF) TEXT_R(STUFF+)
#define TEXT_STAR(STUFF) TEXT_R(STUFF*)
答案 1 :(得分:2)
您的作业无法在C ++中解决。您要么误解了某些内容,要么项目规范中存在错误。无论如何,我们在这里遇到了一个问题:
TEXT(a)+
用于制作正则表达式:std::regex("a+")
,而不会更改TEXT(a)
扩展为"a"
的事实[我的重点]
TEXT(a)
扩展为"a"
- 意思是,我们可以在示例中的任何地方替换TEXT(a)
;毕竟,这正是预处理器的作用。换句话说,您希望编译器转换此C ++代码
"a"+
到
std::regex("a+")
这根本不可能,因为C ++预处理不允许扩展+
令牌。
我们在C ++中可以做的最好的事情是使用运算符重载来生成所需的代码。但是,有两个障碍:
您只能在自定义类型上重载运算符,而"a"
不是自定义类型;它的类型是char const[2]
(为什么2?空终止!)。
Postfix - +
不是有效的C ++运算符,不能重载。
如果你的作业只是有点不同,那就行了。事实上,如果您的作业说TEXT(a)++
应该产生所需的结果,并且您可以更改TEXT
的定义以输出"a"
以外的其他内容,那么我们就会经商:
#include <string>
#include <regex>
#define TEXT(a) my_regex_token(#a)
struct my_regex_token {
std::string value;
my_regex_token(std::string value) : value{value} {}
// Implicit conversion to `std::regex` — to be handled with care.
operator std::regex() const {
return std::regex{value};
}
// Operators
my_regex_token operator ++(int) const {
return my_regex_token{value + "+"};
}
// more operators …
};
int main() {
std::regex x = TEXT(a)++;
}
答案 2 :(得分:1)
您不希望将字符戳到宏的末尾。
也许你只是想要这样的东西:
#define TEXT(a, b) #a #b
那样TEXT(a, +)
扩展为“a”“+”而TEXT(a, *)
扩展为“a”“*”
如果您需要确切的语法,请使用辅助宏,例如:
#define TEXT(a) #a
#define ADDTEXT(x, y) TEXT(x ## y)
这样,ADDTEXT(a, +)
扩展为“a +”,ADDTEXT(a, *)
扩展为“a *”
答案 3 :(得分:0)
你也可以这样做:
#define TEXT(a) "+" // "a" "+" -> "a+"
#define TEXT(a) "*" // "a" "*" -> "a*"
C / C ++中的两个字符串文字将通过规范连接到单个文字中。