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 inline
function. 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 #define
with 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 CStrNullLastNL
is 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.
返回值是内联函数的用途。并且很多时候,内联函数比宏更适合任务,宏非常危险并且没有安全类型。