簡體   English   中英

如何在宏中使用宏后面的代碼塊?

[英]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會出現問題,因為breakcontinue將能夠與之交互,這不好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM