繁体   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