C++ 捕获可变参数模板参数中所有指针包装器的值
C++ capture value of all pointer wrappers in variadic template arguments
std::deque<std::function<std::string()>> log_queue;
void store_log(T&& t, U&&... u) const
{
log_queue.push_back(
[t, u...]() {
return format_log(t, u...));
});
if (log_queue.size() > 1000)
{
log_queue.pop_front();
}
}
我使用上述函数将最新的 1000 条日志消息存储在循环缓冲区中,并在我的开发环境出现问题时打印 log_queue 的内容。
这种方法有问题。一些参数 (U...) 是 pointer wrappers。
因此,当我打印 log_queue 内容时,我看到这些指针的 最后更新值 而不是调用 store_log 函数时的值。我可以通过存储 std::string 而不是 lambda 来解决这个问题,但这非常昂贵(我只想对最后 1000 条日志进行字符串化)。所以我想存储指针包装器包含的值
而不是指针包装器本身。有什么简单的方法吗?
指针包装详细信息:
template <typename T>
class ptr_wrapper
{
T* t = nullptr;
int ref_count = 0;
// constructors and destructors
// functions for updating ref_count whenevr this object is copies/moved etc
};
};
您可以在捕获之前应用转换:
void store_log(T&& t, Us&&... us) const
{
log_queue.push_back(
[tup = std::make_tuple(value(t), value(us)...)]() {
return std::apply([](const auto&... args){ format_log(args...), tup));
});
if (log_queue.size() > 1000)
{
log_queue.pop_front();
}
}
和
template <typename T>
const T& value(const T& value) { return value; }
template <typename T>
std::optional<T> value(const ptr_wrapper<T>& wrapper) {
if (wrapper.t) return *wrapper.t;
return {};
}
// other overloads possible to do deep copy, instead of keeping reference
// ...
C++14的语法;在 C++11 中,您必须在 lambda 之前声明变量。
std::deque<std::function<std::string()>> log_queue;
void store_log(T&& t, U&&... u) const
{
log_queue.push_back(
[t, u...]() {
return format_log(t, u...));
});
if (log_queue.size() > 1000)
{
log_queue.pop_front();
}
}
我使用上述函数将最新的 1000 条日志消息存储在循环缓冲区中,并在我的开发环境出现问题时打印 log_queue 的内容。
这种方法有问题。一些参数 (U...) 是 pointer wrappers。 因此,当我打印 log_queue 内容时,我看到这些指针的 最后更新值 而不是调用 store_log 函数时的值。我可以通过存储 std::string 而不是 lambda 来解决这个问题,但这非常昂贵(我只想对最后 1000 条日志进行字符串化)。所以我想存储指针包装器包含的值 而不是指针包装器本身。有什么简单的方法吗?
指针包装详细信息:
template <typename T>
class ptr_wrapper
{
T* t = nullptr;
int ref_count = 0;
// constructors and destructors
// functions for updating ref_count whenevr this object is copies/moved etc
};
};
您可以在捕获之前应用转换:
void store_log(T&& t, Us&&... us) const
{
log_queue.push_back(
[tup = std::make_tuple(value(t), value(us)...)]() {
return std::apply([](const auto&... args){ format_log(args...), tup));
});
if (log_queue.size() > 1000)
{
log_queue.pop_front();
}
}
和
template <typename T>
const T& value(const T& value) { return value; }
template <typename T>
std::optional<T> value(const ptr_wrapper<T>& wrapper) {
if (wrapper.t) return *wrapper.t;
return {};
}
// other overloads possible to do deep copy, instead of keeping reference
// ...
C++14的语法;在 C++11 中,您必须在 lambda 之前声明变量。