所以不要再被指责 XY problem 这里是全貌:

我正在实现 doctest 并且我想要的当前功能是 INFO() 。它是这样工作的:

int var1 = 1;
{
    int var2 = 666;
    INFO(var1 << "some string" << var2); // INFO is a macro
    // random code...
    CHECK(var1 == 42); // only if this fails should we see the INFO text
}
CHECK(var1 == 42); // INFO is scoped and should not be relevant here

这很简单。除了这个简单的行为之外,我还想要两件事:
  • 我想要懒惰的字符串构造 - 仅当断言失败
  • 我不想要任何分配(至少对于传递给 INFO() 的少量变量) - 我想使用堆栈(使用诸如小缓冲区优化之类的东西)。请注意,我保留了指向字符串化对象的堆栈指针 - 而不是实际的字符串结果。同样在 C++11 右值引用的情况下,我删除了 operator<<&& 重载,因此没有右值可以绑定(bind)到它 - 因为我正在保存指针。

  • 已经 完成了这两件事,但我注意到我的 INFO() 宏不是一个单一的语句。这是一个交易破坏者 - 我不能将整个事情包装在 do { ... } while(false) 中以使其成为单个语句,因为 INFO() 是有范围的 - 这就是它的全部意义......

    这是 INFO() 宏:
    #define INFO_IMPL(name, x) InfoBuilder name; name << x
    #define INFO(x) INFO_IMPL(anon_name, x)
    

    我的竞争对手 CatchINFO() 宏实现为像 this 这样的单个语句,但问题是调用 operator<< 的对象是一个临时对象,它被分配给将在堆栈中的真实对象。
    ScopedMessage anon_name = MessageBuilder() << x; // simplification
    

    这不是我的选择,因为我需要 operator<< 调用的堆栈空间。

    如果我不使用堆栈,那么我将只有懒惰的字符串化 - 但会有分配。

    有没有办法在单个语句中既构造对象又调用方法?像这样的东西:
    InfoBuilder info() << x
    

    而且我在 C++98 中也需要这个。

    我尝试了以下废话(将作用域对象的引用传递给分配给它的对象) - 这不能在 C++ 中工作......
    struct Y;
    
    struct X {
        X(Y&){}
    };
    
    struct Y {
        Y(X&, int){}
    };
    
    int main() {
        X x(Y(x, 6));
    }
    

    最佳答案

    似乎没有一种方法可以在一个语句中创建一个对象并在其上调用一个方法。

    可能的是创建一个 X 类型的临时对象并在其上调用一个方法,然后只要 Y 具有适当的构造函数,该方法的结果就可以分配给 Y 类型的本地对象 - 像这样:

    Y lvalue = X() << arg1 << arg2;
    

    但是为了解决我的问题,我完全按照@Remy Lebeau 在评论中的建议进行了操作-现在我的操作方式与 Catch 相同,但是在构建 InfoBuilder 时我也“窃取”了临时 InfoScope 的内容(小缓冲区)对象 - 带有 InfoBuilder 的复制构造函数。
    #define INFO(x) InfoScope ANONYMOUS(_CAPTURE_)(InfoBuilder() << x)
    

    不知道为什么我昨晚没有想到这个......

    10-08 13:41
    查看更多