如何用 stringstream 类型方法替换 #define

问题描述 投票:0回答:1

我正在尝试替换

#define
函数,如下所示:

#define DEBUG(x) do { std::cout << x << std::endl; } while(0)

具有更多RAII类型的错误跟踪对象。该跟踪对象目前类似于:

class tracker() {
public:
  tracker() = default;
  ~tracker() {
    if( this->stack.empty()) return;
    // dump_the_stack
    // throw (abort)
  }
  void add( const std::string& message ) {
    stack.push_back( message );
  }
private:
  std::vector<const std::string> stack;
};

我想在保留现有

#define
语法的同时使用它。例如,我想要一种方法,允许类用户维护类似于以下之一的语法:

tracker.add( "value exceeded: " << value );

甚至:

tracker << "value exceeded: " << value << std::endl;

理想情况下,我相信我想要的解决方案如下所示:

tracker::add( ostringstream os ) {
  stack.push_back( os.str() + std::endl );
}

但对于第一种情况,似乎没有隐式转换为 ostringstream,并且无法确定

<<
情况下的终结符
operator<<()
。这里有一个我忽略的简单解决方案吗?

c++ c++17
1个回答
0
投票

您可以在临时的析构函数中打印输出,如下所示。

#include <iostream>
#include <vector>
#include <string>

class tracker {
public:
  tracker() = default;
  ~tracker() {
    for (auto item: stack)
    {
        std::cout << item;
    }
  }
  void add( const std::string& message ) {
    stack.push_back( message );
  }
private:
  std::vector<std::string> stack;
};

tracker&&  operator<<(tracker&& tr, std::string item)
{
    tr.add(item);
    return std::move(tr);
}

#define DEBUG(X) tracker{} << X

int main()
{
    DEBUG("hello" << " " << "world!");
}

一个不幸的副作用是需要执行

return std::move(tr);
但由于该对象的生命周期一直延伸到结束分号,因此它应该可以工作。

© www.soinside.com 2019 - 2024. All rights reserved.