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

防止解构宏中定义的匿名变量,直到作用域结束

  •  1
  • Stradigos  · 技术社区  · 8 年前

    我试图利用类构造函数和解构器通过RAII习惯用法来表示和格式化日志文件中的作用域。使用单个 #define ,它打印“{”,并增加全局缩进级别,以便在该缩进级别打印下一个记录行。

    LogScopeRAII 应该打印“}”,并自然减少全局缩进级别,因为它在结束时超出范围 Foo() 然而,我看到的行为是,LogScopeRAII在构建后立即解构。

    假设 答:我认为问题在于LogScopeRAII是在分配的RHS上创建的(因此是匿名的?)并在最后被摧毁,但我不知道该怎么办。我想 LOG_ANONYMOUS_VARIABLE 在里面 VSCOPE_F 本来会做的把戏,使它留下来,但事实并非如此。

    问题 :如何阻止LogScopeRAII解构,直到调用函数超出范围?

    /* Header */
    LogScopeRAII::LogScopeRAII(Verbosity verbosity, const char* file, unsigned line, const char* format, ...)
    {
        // ...
        // print "{" and then increase an indentation global var
    }
    
    LogScopeRAII::~LogScopeRAII()
    {
        // ...
        // print "}" and then decrease the indentation global var
    }
    
    #define LOG_ANOMYMOUS_VARIABLE(str) LOG_CONCAT(str, __LINE__)
    
    #define VSCOPE_F(verbosity, ...) \
    LogScopeRAII LOG_ANONYMOUS_VARIABLE(raii) = \
    ((verbosity) > verb_cutoff() ? LogScopeRAII() : LogScopeRAII{verbosity, __FILE__, __LINE__, __VA_ARGS__}
    
    #define SCOPE_F(verbosity_name, ...) VSCOPE_F(Verbosity_ ## verbosity_name, __VA_ARGS__)
    
    #define SCOPE_FUNCTION(INFO) SCOPE_F(verbosity_name, __FUNCTION__)
    
    /* Implementation */
    void Foo()
    {
        SCOPE_FUNCTION(INFO) // print "{" and increase indentation
        for (size_t i = 0; i < 3; ++i)
        {
            // do work
            LOG(INFO, "Work logged");
        }
        // print "}" and decrease indentation
    }
    

    期望输出:

    { Foo()
        "Work Logged" // Note indentation
    } 0.23 s: Foo()
    

    编辑:简化问题

    问题的关键在于:三元结构似乎不起作用。

    这是有效的:

    LogScopeRAII a(LogScopeRAII{ Verbosity_INFO, __FILE__, static_cast<unsigned>(__LINE__), "" });
    

    但这并不:

    LogScopeRAII a(((Verbosity_INFO) > indent) ? LogScopeRAII() : LogScopeRAII{ Verbosity_INFO, __FILE__, static_cast<unsigned>(__LINE__), "" });
    

    我得到:

    {
    }
    Work logged
    Work logged
    Work logged
    }
    constructCounter: 1
    destructCounter: 2
    Exiting...
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Jarod42    8 年前
    #define VSCOPE_F(verbosity, ...) \
    LogScopeRAII LOG_ANONYMOUS_VARIABLE(raii) = \
    ((verbosity) > verb_cutoff() ? LogScopeRAII() : LogScopeRAII{verbosity, __FILE__, __LINE__, __VA_ARGS__}
    

    应该是

    #define VSCOPE_F(verbosity, ...) \
    LogScopeRAII LOG_ANONYMOUS_VARIABLE(raii) \
    (((verbosity) > verb_cutoff() ? LogScopeRAII() : LogScopeRAII{verbosity, __FILE__, __LINE__, __VA_ARGS__})
    

    否则使用临时变量的复制构造函数。

    (您还可以修复移动构造函数和析构函数以允许当前宏的问题。)