问题描述
我正在编写一个日志类,它使用源位置作为默认参数。
我想要一个类似 printf 的函数调用,我希望使用 CTAD 应该可以实现,但在这种情况下,它用于模板化函数而不是模板化类,所以很明显 vlog
不是类型(它是一个函数)因此错误。
不太确定我哪里出错了或者这是否真的可能??
log
采用基本的字符串视图并且工作正常。
vlog
是采用 printf 样式参数列表的“聪明”位,即 const char*
然后是不同类型的可变参数。我已尝试包含尽可能多的代码,以防有更好的方法!
C++17 并提前致谢。
#include <chrono>
#include <experimental/source_location>
#include <mutex>
#include <string_view>
#include <string>
#include <iostream>
namespace LOGGING
{
class Logging
{
using Ms = std::chrono::milliseconds; ///< typename alias
using source_location = std::experimental::source_location; ///< typename alias
constexpr static Ms defalt_mutex_wait{100};
public:
static bool log(const std::string_view& msg,const source_location& location = source_location::current())
{
if (mutx.try_lock_for(defalt_mutex_wait))
{
std::cout << location.file_name() << "[" << \
location.line() << ":" << \
location.function_name() << "]: " << \
msg;
std::cout << std::endl; // flush
mutx.unlock();
return true;
}
return false;
}
template <typename... T>
static bool vlog(const char*&& fmt,T&&... vars,const source_location& location = source_location::current())
{
if (mutx.try_lock_for(defalt_mutex_wait))
{
char buf[100]{};
snprintf(buf,sizeof(buf),fmt,vars...);
std::cout << location.file_name() << "[" << \
location.line() << ":" << \
location.function_name() << "]: " << \
buf;
std::cout << std::endl; // flush
mutx.unlock();
return true;
}
return false;
}
template <typename... T>
vlog(const char*,T&&...) -> vlog<T...>;
template<class Rep,class Period>
[[nodiscard]] static bool lock(std::unique_lock<std::recursive_timed_mutex>& lock,const std::chrono::duration<Rep,Period>& timeout_duration = Ms(100))
{
if (mutx.try_lock_for(timeout_duration))
{
lock = std::move(std::unique_lock<std::recursive_timed_mutex>(mutx));
mutx.unlock();
return true;
}
return false;
}
static bool lock(std::unique_lock<std::recursive_timed_mutex>& lock)
{
lock = std::move(std::unique_lock<std::recursive_timed_mutex>(mutx));
return true;
}
private:
Ms instance_mutex_wait{defalt_mutex_wait};
public:
Logging(void) noexcept = default;
private:
static std::recursive_timed_mutex mutx;
};
inline std::recursive_timed_mutex Logging::mutx{};
inline Logging LOG;
} // namespace LOGGING
int main()
{
using namespace LOGGING;
LOG.log("Hello world!");
LOG.vlog<int>("Value is %d",42);
LOG.vlog("Value is %d",42); // HERE
return 0;
}
<source>:58:34: error: 'vlog<T ...>' does not name a type
58 | vlog(const char*,T&&...) -> vlog<T...>;
| ^~~~~~~~~~
<source>:58:44: error: expected constructor,destructor,or type conversion before ';' token
58 | vlog(const char*,T&&...) -> vlog<T...>;
任何感兴趣的人的上下文;它适用于多线程和多核嵌入式系统(ESP32),主要需要防止不同的线程日志消息交错。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)