Macro to add character at end of string without passing source string
我正在尝试编写一个宏,它在字符串末尾添加一个字符(结束功能键)而不传递源字符串。
声明:
1
|
LEVEL_ENTRY(level) <<“Level1 Message”;
|
预期的宏扩展
1
|
LEVEL_ENTRY(level) levelParser(level, std::ostringstream().flush() <<“Level1 Message”);
|
我正在尝试这样
1
|
#define LEVEL_ENTRY(level) levelParser(level, std::ostringstream().flush()
|
C 宏可以进行这种扩展(不传递参数)吗?
编辑
为了让它现在能正常工作,我正在做类似的事情
1
2 3 |
#define LEVEL_ENTRY(level, msg) levelParser(level, std::ostringstream().flush() << msg)
LEVEL_ENTRY(level,“Level1 Message”<<“Message2”); |
真正的问题是我现在不能简单地更改语句’它在项目中的 1000 多个地方使用。
- 您的宏是”有效的”,但生成的代码不是。因此,最终结果无效。
- @sujin – 花点时间重新阅读您的问题,您的”预期宏扩展”是无效的 C 并且还包含宏。
- 粗略地说,如果你想让事情与宏一起正常工作,请使用将相关材料作为参数的宏。你说,你有 1000 个这种表示法的实例。所以,用 sed 在现代机器上修复应该需要几秒钟,即使它在 1000 个文件中的每个文件中只出现一次,并且文件每个 20K 行和总共 1 MiB,这不太可能.如果您(或您的前任之一)错误地设计了某些东西,则可能需要在需求发生变化时进行彻底的努力来修复它。
不,你不能将 << 东西放到宏中。宏由预处理器处理,C 语言解析器看不到,宏不支持任何类型的 << 语法。
A macro is a fragment of code which has been given a name. Whenever the name is used, it is replaced by the contents of the macro. There are two kinds of macros. They differ mostly in what they look like when they are used. Object-like macros resemble data objects when used, function-like macros resemble function calls.
https://gcc.gnu.org/onlinedocs/cpp/Macros.html
- 谢谢你的解释。请看我更新的问题
- 您更新的问题仍然意味着您希望宏扩展到传递给它的参数之外(您的预期语句在 <<“Level1 Message” 之后有一个 \\’)\\’)。我会为我的问题写一个小编辑。
- 我无法更改我现有的声明。它在项目中的 1000 多个地方使用
- 您说您要生成以下代码: LEVEL_ENTRY(level) levelParser(level, std::ostringstream().flush() <<“Level1 Message”); 这是无效的 C ,并且您要生成它的语句是 LEVEL_ENTRY(level) <<“Level1 Message”。你问的是不可能的。宏对 << 一无所知,并且不可能编写一个宏,在传递给它的参数之外的语句末尾任意添加一个结束 ) :(
- 我期望的宏扩展是有效的 C 语法。我将类型传递给标准字符串流。请检查我的编辑,我如何设法实现这一目标。
- 同样,您不能使用宏来执行此操作,请参阅 Bill Lynch 对非宏解决方案的回答。
- 感谢您的澄清
解决问题的一种方法是:
1
2 3 4 5 6 7 8 |
struct Foo { int level; };
auto operator<<(Foo foo, char const *s) #define LEVEL_ENTRY(level) Foo{level} |
- 请注意,这不适用于 LEVEL_ENTRY(3) <<“foo” <<“bar”;,但这可能超出了要求。
- @Bill Lynch 您的评论是我的确切要求,这就是我使用 ostringstream 的原因。 LEVEL_ENTRY(3) << “foo” << “bar” << var1 << stringvar;
- @sujin您是否希望将所有流式传输的结果传递给levelParser?更新问题的第一部分以包含此用法会很好吗?
- BTW ostringstream().flush() 与 ostringstream() 相同,为空时没有什么要刷新的
当然可以,但不涉及宏:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
class LEVEL_ENTRY {
public: LEVEL_ENTRY(level): level_(level) {} LEVEL_ENTRY(LEVEL_ENTRY const &) = delete; LEVEL_ENTRY & operator=(LEVEL_ENTRY const &) = delete; ~LEVEL_ENTRY() { LEVEL_ENTRY & operator<<(const char *message) { private: LEVEL_ENTRY(1) <<“Level1 Message”; |
- 为每个语句创建一个类的实例不是一个好主意。
- @sujin 为什么不呢?实际上,您使用 ostringstream 类的实例正是这样做的。
来源:https://www.codenong.com/35907232/