首页 > 解决方案 > 如何在c ++中的多个位置访问类的模板化静态变量

问题描述

我正在用 C++ 开发一个功能模拟器项目。我的目标是将最后 50 个调试日志语句存储在滚动缓冲区中,并在模拟器中出现错误时显示它们。这将有助于更快地调试。否则,当出现错误时,我将不得不记下周期,并在启用日志的情况下重新运行模拟器,这既费时又慢。

在文件 abc.h 日志结构中存储调试日志语句、生成日志的模拟周期等

template <typename T, typename... U>
struct Logging {
    ......
}

abc.h 中的以下模板化类包含一个静态成员,该成员是包含最后 50 个日志调试语句的滚动窗口

template <typename T> 
class LogGlobal {
   public:    
       static std::deque<T> last_50_logs; //rolling window of last 50 log statements

};
template <typename T> std::deque<T> LogGlobal<T>::last_50_logs = {};

在 abc.h 的 debug_log 函数中,我将一些对象推送到静态变量,如下所示:

template <typename T, typename... U>
void debug_log(T&& t, U&&... u) const
{
    //other code to ensure that this deque holds last 50 log statements only is not written here for simplicity
    LogGlobal<Logging<T, U...>>::last_50_logs.push_back(<Logging<T, U...>{...}); 
}

在 abc.cpp 文件中,我们有一个错误处理函数,只要模拟器中出现错误,就会调用该函数。

void error_handler()
{
    //I want to access the last_50_logs static variable here but I don't have information about the template T and U here. How do I solve this?
} 

在 error_handler 函数中,我无权访问用于创建 LogGlobal 类的模板类型。有没有办法或解决方法来了解这些细节?

解决此问题的一种方法是,每当我推送到 last_50_logs 时,我都可以将日志语句存储为 std::string,而不是在 Logging 结构中的模板 T 和 U。但这真的很慢,因为字符串操作很昂贵。

标签: c++c++11templatesc++14c++17

解决方案


解决此问题的一种方法是,每当我推送到 last_50_logs 时,我都可以将日志语句存储为 std::string,而不是在 Logging 结构中的模板 T 和 U。但这真的很慢,因为字符串操作很昂贵。

好吧,您不能将日志事件存储为某种未知类型T,因为......那么您不知道该类型是什么。

但是,您可以使用某种类型的擦除来推迟格式化,直到(除非)您确实需要该字符串。例如,你可以std::function<std::string()>在你的双端队列中存储一个对象,

using DeferredLog = std::function<std::string()>;
class LogGlobal {
   public:    
       static std::deque<DeferredLog> last_50_logs; //rolling window of last 50 log statements
};

template <typename T, typename... U>
void debug_log(T&& t, U&&... u) const
{
    // blah blah blah circular buffer
    LogGlobal<Logging<T, U...>>::last_50_logs.push_back(
      [t, u...] () { return format_log(t, u...); }
    ); 
}

请注意,类型擦除确实有一些开销,并且所有参数都需要按值捕获,因此不能保证比格式化固定宽度的字符串更快。对其进行基准测试并查看。std::function如果看起来值得的话,您总是可以手动滚动一些不如使用 lambda 捕获的通用的东西。


推荐阅读