锁定宏中的ostream输出

时间:2015-06-25 12:28:56

标签: c++ cout

我有一些专有记录器的代码:

#define LOG GetStream()

GetStream返回std :: ostream的位置。用户会这样做:

LOG << "text";

我需要这是线程安全的,但我想避免这种情况:

#define END Unlock();
#define LOG Lock(); GetStream() << "text" << END;

由于用户需要添加&#34; END&#34;:

LOG << "Text" << END;

有什么想法吗?

备注:我使用this之类的东西处理回车。

3 个答案:

答案 0 :(得分:2)

解决此问题的一种方法是使用函数式宏,在这里使用C ++块和范围包含锁定/解锁:

#define LOG(output)               \
    do                            \
    {                             \
        LockingClass lock;        \
        GetStream() << output;    \
    } while (0)

LockingClass(或者你想要命名的任何东西)是一个范围锁,它在构造时锁定流,并在销毁时将其解锁。

可以像例如一样使用。

LOG("hello variable is " << variable);

不能将它与包含逗号的表达式一起使用,但预处理器会将逗号解释为宏的参数分隔符。可能可以用variadic macros来解决。

答案 1 :(得分:1)

尽管如此:

#define LOG for (int i = 0 ;i < 1 ;i++,(i == 1 ? Unlock())) LockAndGetStream()

答案 2 :(得分:0)

TL; TD:你不能只让宏x<<text<<end工作。

为了将带有分号(;)的许多表达式与宏放在一起,唯一有效的方法是使用do{..} while(0)语句,您可以在此处阅读更多内容:do { ... } while (0) — what is it good for?

现在,除非您想使用<<之类的某些运算符,否则您无法使用do{..} while(0) costruct。

我的建议:将std::ostream包装在重载<<运算符的类中。在重载内,请致电LockUnlock

struct MyLogger{
  std::ostream& operator << (Text text){
    Lock();
    stream <<text;
    Unlock();
    return stream;
  }
}

其中stream是您将文本流式传输到的流。

现在,您可以从此类创建一个对象并使用常规的非宏<<

NyLogger Log;
Log << text;