我正在尝试替换
#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<<()
。这里有一个我忽略的简单解决方案吗?
您可以在临时的析构函数中打印输出,如下所示。
#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);
但由于该对象的生命周期一直延伸到结束分号,因此它应该可以工作。