[英]How to use the block of code following the macro in the macro?
我想用它的宏來實現像 Boost 庫一樣的東西(例如,就像BOOST_FOREACH
一樣)。
這是我目前使用的宏示例:
#define LOCK_GUARD(var, block) { std::lock_guard<std::mutex> ___scope__(var); block }
std::mutex mutex;
LOCK_GUARD(mutex, {
// body...
});
我想知道如何以這種方式修改它,所以我可以使用LOCK_GUARD
,如下所示:
LOCK_GUARD(mutex)
{
// body...
}
編輯:雖然它適用於 C,但我認為可能定義一個帶有變量主體的函數式宏的公認答案? 可以在這里使用。
可以通過使用for
循環以這種方式創建宏。 例子:
#include <iostream>
struct Foo {
int bar;
Foo(int bar) : bar(bar) { std::cout << 1 << std::endl; }
~Foo() { std::cout << 3 << std::endl; }
};
#define TEST(var) \
for (bool flag = true; flag; ) \
for (Foo foo(var); flag; flag = false)
int main()
{
int x = 2;
TEST(x) {
std::cout << foo.bar << std::endl;
}
// std::cout << foo.bar << std::endl; // ERROR: ‘foo’ was not declared in this scope
std::cout << 4 << std::endl;
return 0;
}
如果flag
為真,則兩個循環都將執行。 第一個循環將flag
初始化為此值。 第二個循環創建 object foo
。 擴展后, TEST
的“主體”成為第二個循環的主體。 執行代碼后(在 body 中聲明的所有內容現在都應該被正確銷毀),第二個循環將flag
設置為 false 並因此結束。 第一個循環也結束並銷毀flag
。
問題是,你想在多線程程序中使用它。 這種方法肯定會導致數據競爭。
就個人而言,我不會玩這樣的宏,而只是簡單地以這種方式做一些事情:
using mutex_lock_guard = std::lock_guard<std::mutex>;
std::mutex;
void func(int x)
{
// init...
{
mutex_lock_guard lock(mutex);
// body..
}
}
或者仍然使用宏:
#define LOCK_GUARD(var) std::lock_guard<std::mutex> lock(var)
std::mutex;
void func(int x)
{
// init...
{
LOCK_GUARD(mutex);
// body..
}
}
在if
條件中定義變量。 那么你的代碼塊可以是if
主體。
#define LOCK_GUARD(var) \
if (::std::lock_guard<std::mutex> _lock_guard_(var); false) {} else
注意false) {} else
而不是true)
- 它防止用戶代碼中的else
附加到宏。
請注意,使用循環(僅執行一次)代替if
會出現問題,因為break
和continue
將能夠與之交互,這不好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.