C++ 让宏“返回”一个值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2679182/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Have macro 'return' a value
提问by bobobobo
I'm using a macro and I think it works fine -
我正在使用宏,我认为它工作正常 -
#define CStrNullLastNL(str) {char* nl=strrchr(str,'\n'); if(nl){*nl=0;}}
So it works to zero out the last newline in a string, really its used to chop off the linebreak when it gets left on by fgets.
因此,它可以将字符串中的最后一个换行符清零,实际上它用于在 fgets 留下换行符时切断换行符。
So, I'm wondering if I can "return" a value from the macro, so it can be called like
所以,我想知道我是否可以从宏“返回”一个值,所以它可以像
func( CStrNullLastNL( cstr ) ) ;
Or will I have to write a function
或者我必须写一个函数
回答by Mike DeSimone
For a macro to "return a value", the macro itself has to be an expression. Your macro is a statement block, which cannot evaluate to an expression.
对于要“返回值”的宏,宏本身必须是一个表达式。您的宏是一个语句块,不能计算为表达式。
You really ought to write an inlinefunction. It will be just as fast and far more maintainable.
你真的应该写一个inline函数。它将同样快速且更易于维护。
回答by Danvil
#define CStrNullLastNL(str) ({ \
char* nl=strrchr(str,'\n');\
if(nl){*nl=0;} \
nl; \
})
should work.
应该管用。
Edit: ... in GCC.
编辑:...在海湾合作委员会中。
回答by i_am_jorf
Macro's don't return values. Macros tell the preprocessor to replace whatever is after the #definewith whatever is after the thing after the #define. The result has to be valid C++.
宏不返回值。宏告诉预处理器将 之后的内容替换为 之后的#define内容#define。结果必须是有效的 C++。
What you're asking for is how to make the following valid:
您要求的是如何使以下内容有效:
func( {char* nl=strrchr(str,'\n'); if(nl){*nl=0;}} );
I can't think of a good way to turn that into something valid, other than just making it a real function call. In this case, I'm not sure why a macro would be better than an inline function. That's seems to be what you're really asking for.
除了让它成为真正的函数调用之外,我想不出一个好的方法来将它变成有效的东西。在这种情况下,我不确定为什么宏会比内联函数更好。这似乎是你真正要求的。
回答by MSN
If you really want to do this, get a compiler that supports C++0x style lambdas:
如果您真的想这样做,请获取支持 C++0x 样式 lambdas 的编译器:
#define CStrNullLastNL(str) [](char *blah) {char* nl=strrchr(blah,'\n'); if(nl){*nl=0;} return blah;}(str)
Although since CStrNullLastNLis basically a function you should probably rewrite it as a function.
尽管因为CStrNullLastNL基本上是一个函数,但您可能应该将其重写为函数。
回答by Adisak
Can you use the comma operator? Simplified example:
可以使用逗号运算符吗?简化示例:
#define SomeMacro(A) ( DoWork(A), Permute(A) )
Here B=SomeMacro(A) "returns" the result of Permute(A) and assigns it to "B".
这里 B=SomeMacro(A) “返回” Permute(A) 的结果并将其分配给“B”。
回答by gatis paeglis
If you don't have a strict requirement to use only macro, you can do something like this (real life example):
如果你没有严格要求只使用宏,你可以做这样的事情(现实生活中的例子):
#define Q_XCB_SEND_EVENT_ALIGNED(T) \
q_xcb_send_event_aligned<T>()
template<typename T> inline
T q_xcb_send_event_aligned()
{
union {
T event;
char padding[32];
} event;
memset(&event, 0, sizeof(event));
return event.event;
}
And then use it in your code like this:
然后在您的代码中使用它,如下所示:
auto event = Q_XCB_SEND_EVENT_ALIGNED(xcb_unmap_notify_event_t);
回答by Potatoswatter
I gave +1 to Mike because he's 100% right, but if you want to implement this as a macro,
我给了 Mike +1,因为他 100% 是正确的,但是如果你想把它作为一个宏来实现,
char *CStrNullLastNL_nl; // "private" global variable
#define nl ::CStrNullLastNL_nl // "locally" redeclare it
#define CStrNullLastNL( str ) ( \
( nl = strrchr( str, '\n') ), /* find newline if any */ \
nl && ( *nl = 0 ), /* if found, null out */ \
(char*) nl /* cast to rvalue and "return" */ \
OR nl? str : NULL /* return input or NULL or whatever you like */
)
#undef nl // done with local usage
回答by Michael Dorgan
Returning a value is what inline functions are for. And quite often, said inline functions are better suited to tasks than macros, which are very dangerous and have no type safetly.
返回值是内联函数的用途。并且很多时候,内联函数比宏更适合任务,宏非常危险并且没有安全类型。

