代码之家  ›  专栏  ›  技术社区  ›  SupAl

避免在没有宏的情况下构建对象

  •  -1
  • SupAl  · 技术社区  · 1 年前

    我有一个记录器,它在代码中多个位置使用,它获取字符串并打印它,还有另一个函数告诉我日志是否已启用:

    void log_msg(std::string const& msg);
    bool is_log_enabled();
    

    当日志被禁用时,我想避免(可能昂贵的)字符串构造,如下所示:

    void some_func()
    {
       log_msg(std::string("some_string: ") + std::to_string(500) + std::string(" even more string...");
    }
    

    当运行上述操作时,将在将整个字符串传递给 log_msg 函数,如果未启用日志,该函数甚至可能不会使用它。

    我知道我可以使用:

    #define log(msg) \
       if (is_log_enabled()) { \
          log_msg(msg); \
       } 
    

    为了避免串结构,但有没有办法做到这一点 没有 宏的使用,因为它们通常不建议使用?

    内联函数可能解决问题吗

     void inline log_msg(std::string const& msg) \
       if (is_log_enabled()) { \
          log_msg(msg); \
       } 
    

    或者这保证了构造函数参数(即,即使在禁用日志的情况下也构造字符串)?

    1 回复  |  直到 1 年前
        1
  •  2
  •   user17732522    1 年前

    您使用函数的方法将构建 std::string 而不管日志是否被启用。当然,编译器可能会进行优化。

    C++没有延迟求值的函数参数。但是,可以通过传递函数调用的lambda来模拟它们:

    void log_msg(auto generator) {
        if (is_log_enabled())
            real_log_msg(std::invoke(generator));
    }
    
    //...
    
    log_msg([&]{ return std::string("some_string: ") + std::to_string(500) + std::string(" even more string..."); });
    

    不幸的是,对于这样一个单一的lambda表达式,目前没有更简洁的语法。希望它能在未来的C++版本中出现。然而,您当然可以为特定的、更通用的目的编写宏。