修改了一些报错消息,并使用数据库存储报错信息,以便后续查阅

This commit is contained in:
jinchao 2025-06-06 17:03:35 +08:00
parent 25ca69597b
commit 069ea0ea37
7 changed files with 176 additions and 126 deletions

BIN
Release/database/LogInfo.db Normal file

Binary file not shown.

View File

@ -75,7 +75,7 @@ protected:
} }
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型"); "T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 78");
} }
return result; return result;
@ -109,7 +109,7 @@ protected:
setByteArrayFromStdArray(data.value(), thisArray); setByteArrayFromStdArray(data.value(), thisArray);
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型"); "T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 112");
} }
} }
@ -132,7 +132,7 @@ protected:
getTypeSize<T>()); getTypeSize<T>());
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型"); "T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 135");
} }
} }
@ -158,7 +158,7 @@ protected:
setByteArrayFromStdArray(data[i], subArray); setByteArrayFromStdArray(data[i], subArray);
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型"); "T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 160");
} }
} }
} }
@ -175,7 +175,7 @@ protected:
if (data) { if (data) {
return std::to_string(data.value()); return std::to_string(data.value());
} else { } else {
return std::to_string(0); return "Unknown";
} }
} else if constexpr (is_std_array_v<T>) { } else if constexpr (is_std_array_v<T>) {
if (data) { if (data) {
@ -186,7 +186,7 @@ protected:
} }
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型"); "T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 188");
} }
return std::string(); return std::string();
} }
@ -218,7 +218,7 @@ protected:
data = temp; data = temp;
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型"); "T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 220");
} }
} }
@ -240,7 +240,7 @@ protected:
ss << getStringFromStdArray(data[i]); ss << getStringFromStdArray(data[i]);
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型"); "T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 243");
} }
} }
return ss.str(); return ss.str();
@ -272,8 +272,9 @@ protected:
// 对于嵌套数组,递归处理 // 对于嵌套数组,递归处理
start_pos = setStdArrayFromString(data[i], value, start_pos + i); start_pos = setStdArrayFromString(data[i], value, start_pos + i);
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(
"T 必须是算术类型或std::array类型"); std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 275");
} }
} catch (const std::exception &e) { } catch (const std::exception &e) {
throw std::runtime_error("无法解析第 " + std::to_string(i) throw std::runtime_error("无法解析第 " + std::to_string(i)
@ -289,8 +290,10 @@ protected:
if (data) { if (data) {
auto temp = data.value(); auto temp = data.value();
if constexpr (std::is_arithmetic_v<T1>) { if constexpr (std::is_arithmetic_v<T1>) {
static_assert(std::is_arithmetic_v<T2>, "模板参数T2必须是算术类型"); static_assert(std::is_arithmetic_v<T2>,
static_assert(std::is_convertible_v<T1, T2>, "模板参数T1必须可以转换为T2类型"); "模板参数T2必须是算术类型详见XNDDSInterface.cppline 293");
static_assert(std::is_convertible_v<T1, T2>,
"模板参数T1必须可以转换为T2类型详见XNDDSInterface.cppline 295");
model_data = temp; model_data = temp;
} else if constexpr (is_std_array_v<T1>) { } else if constexpr (is_std_array_v<T1>) {
size_t arraySize = array_size_v<T1>; size_t arraySize = array_size_v<T1>;
@ -308,18 +311,21 @@ protected:
} }
} else { } else {
static_assert(std::is_arithmetic_v<sub_array_type>, static_assert(std::is_arithmetic_v<sub_array_type>,
"模板参数T1是std::array类型时它的数组嵌套不能超过两层"); "模板参数T1是std::"
"array类型时它的数组嵌套不能超过两层详见XNDDSInterfac"
"e.cppline 313");
} }
} else { } else {
static_assert(std::is_arithmetic_v<array_type> static_assert(
|| is_std_array_v<array_type>, std::is_arithmetic_v<array_type> || is_std_array_v<array_type>,
"模板参数T1是std::array类型时它的value_" "模板参数T1是std::array类型时它的value_"
"type必须是算术类型或std::array类型"); "type必须是算术类型或std::array类型详见XNDDSInterface.cppline 320");
} }
} }
} else { } else {
static_assert(std::is_arithmetic_v<T1> || is_std_array_v<T1>, static_assert(
"模板参数T1必须是算术类型或std::array类型"); std::is_arithmetic_v<T1> || is_std_array_v<T1>,
"模板参数T1必须是算术类型或std::array类型详见XNDDSInterface.cppline 326");
} }
} }
} }
@ -328,8 +334,10 @@ protected:
void assign_value_set(eprosima::fastcdr::optional<T1> &data, const T2 &model_data) void assign_value_set(eprosima::fastcdr::optional<T1> &data, const T2 &model_data)
{ {
if constexpr (std::is_arithmetic_v<T1>) { if constexpr (std::is_arithmetic_v<T1>) {
static_assert(std::is_arithmetic_v<T2>, "模板参数T2必须是算术类型"); static_assert(std::is_arithmetic_v<T2>,
static_assert(std::is_convertible_v<T2, T1>, "模板参数T2必须可以转换为T1类型"); "模板参数T2必须是算术类型详见XNDDSInterface.cppline 337");
static_assert(std::is_convertible_v<T2, T1>,
"模板参数T2必须可以转换为T1类型详见XNDDSInterface.cppline 339");
data = model_data; data = model_data;
} else if constexpr (is_std_array_v<T1>) { } else if constexpr (is_std_array_v<T1>) {
T1 temp; T1 temp;
@ -347,18 +355,22 @@ protected:
} }
} else { } else {
static_assert(std::is_arithmetic_v<sub_array_type>, static_assert(std::is_arithmetic_v<sub_array_type>,
"模板参数T1是std::array类型时它的数组嵌套不能超过两层"); "模板参数T1是std::"
"array类型时它的数组嵌套不能超过两层详见XNDDSInterface."
"cppline 357");
} }
} else { } else {
static_assert(std::is_arithmetic_v<array_type> || is_std_array_v<array_type>, static_assert(
"模板参数T1是std::array类型时它的value_" std::is_arithmetic_v<array_type> || is_std_array_v<array_type>,
"type必须是算术类型或std::array类型"); "模板参数T1是std::array类型时它的value_"
"type必须是算术类型或std::array类型详见XNDDSInterface.cppline 364");
} }
} }
data = temp; data = temp;
} else { } else {
static_assert(std::is_arithmetic_v<T1> || is_std_array_v<T1>, static_assert(
"模板参数T1必须是算术类型或std::array类型"); std::is_arithmetic_v<T1> || is_std_array_v<T1>,
"模板参数T1必须是算术类型或std::array类型详见XNDDSInterface.cppline 371");
} }
} }

View File

@ -178,46 +178,59 @@ public:
} }
private: private:
// 辅助函数,用于格式化消息 /**
* @brief
* @tparam T
* @param arg
* @return
*/
template <typename T> template <typename T>
static std::string convertToString(const T &arg) static std::string convertToString(const T &arg)
{ {
if constexpr (std::is_arithmetic<T>::value) { if constexpr (std::is_arithmetic_v<T>) {
return std::to_string(arg); // 处理数值类型 return std::to_string(arg); // 处理数值类型
} else { } else if constexpr (std::is_same_v<T, std::string>) {
return arg;
} else if constexpr (std::is_convertible_v<T, std::string>) {
return std::string(arg); return std::string(arg);
} else if constexpr (std::is_same_v<T, char *> || std::is_same_v<T, const char *>) {
return std::string(arg);
} else {
static_assert(std::is_arithmetic_v<T> || std::is_same_v<T, std::string>
|| std::is_convertible_v<T, std::string> || std::is_same_v<T, char *>
|| std::is_same_v<T, const char *>,
"错误码010211001不支持的类型转换详见XNLogger.cppline 199");
} }
} }
// 递归变参函数,用于处理多个参数 /**
template <typename T, typename... Args> * @brief %1%2%3
static std::string formatMessage(const std::string &message, T arg, Args... args) * @tparam Args
* @param message
* @param args
* @return
*/
template <typename... Args>
static std::string formatMessage(const std::string &message, Args &&...args)
{ {
// 查找下一个参数占位符 static_assert(sizeof...(Args) <= 9,
"错误码010211002单条日志参数数量超过限制详见XNLogger.cppline 216");
std::string result = message; std::string result = message;
size_t paramIndex = 0; // 使用初始化列表展开参数包
size_t pos = 0; int index = 1;
// 使用lambda和std::initializer_list展开参数包
// 找到当前参数对应的占位符 (void)std::initializer_list<int>{(
while (true) { [&result, &index](const auto &value) {
std::string placeholder = "%" + std::to_string(paramIndex + 1); std::string placeholder = "%" + std::to_string(index++);
pos = result.find(placeholder); size_t pos = result.find(placeholder);
if (pos != std::string::npos) { if (pos != std::string::npos) {
// 替换占位符使用placeholder的长度 result.replace(pos, placeholder.length(), convertToString(value));
result.replace(pos, placeholder.length(), convertToString(arg)); }
break; }(args),
} 0)...};
paramIndex++; return result;
if (paramIndex > 100) { // 防止无限循环
return result;
}
}
return formatMessage(result, args...);
} }
// 基础情况
static std::string formatMessage(const std::string &message) { return message; }
}; };
/** /**

View File

@ -75,7 +75,7 @@ protected:
} }
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型"); "T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 78");
} }
return result; return result;
@ -109,7 +109,7 @@ protected:
setByteArrayFromStdArray(data.value(), thisArray); setByteArrayFromStdArray(data.value(), thisArray);
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型"); "T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 112");
} }
} }
@ -132,7 +132,7 @@ protected:
getTypeSize<T>()); getTypeSize<T>());
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型"); "T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 135");
} }
} }
@ -158,7 +158,7 @@ protected:
setByteArrayFromStdArray(data[i], subArray); setByteArrayFromStdArray(data[i], subArray);
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型"); "T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 160");
} }
} }
} }
@ -186,7 +186,7 @@ protected:
} }
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型"); "T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 188");
} }
return std::string(); return std::string();
} }
@ -218,7 +218,7 @@ protected:
data = temp; data = temp;
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型"); "T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 220");
} }
} }
@ -240,7 +240,7 @@ protected:
ss << getStringFromStdArray(data[i]); ss << getStringFromStdArray(data[i]);
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型"); "T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 243");
} }
} }
return ss.str(); return ss.str();
@ -272,8 +272,9 @@ protected:
// 对于嵌套数组,递归处理 // 对于嵌套数组,递归处理
start_pos = setStdArrayFromString(data[i], value, start_pos + i); start_pos = setStdArrayFromString(data[i], value, start_pos + i);
} else { } else {
static_assert(std::is_arithmetic_v<T> || is_std_array_v<T>, static_assert(
"T 必须是算术类型或std::array类型"); std::is_arithmetic_v<T> || is_std_array_v<T>,
"T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 275");
} }
} catch (const std::exception &e) { } catch (const std::exception &e) {
throw std::runtime_error("无法解析第 " + std::to_string(i) throw std::runtime_error("无法解析第 " + std::to_string(i)
@ -289,8 +290,10 @@ protected:
if (data) { if (data) {
auto temp = data.value(); auto temp = data.value();
if constexpr (std::is_arithmetic_v<T1>) { if constexpr (std::is_arithmetic_v<T1>) {
static_assert(std::is_arithmetic_v<T2>, "模板参数T2必须是算术类型"); static_assert(std::is_arithmetic_v<T2>,
static_assert(std::is_convertible_v<T1, T2>, "模板参数T1必须可以转换为T2类型"); "模板参数T2必须是算术类型详见XNDDSInterface.cppline 293");
static_assert(std::is_convertible_v<T1, T2>,
"模板参数T1必须可以转换为T2类型详见XNDDSInterface.cppline 295");
model_data = temp; model_data = temp;
} else if constexpr (is_std_array_v<T1>) { } else if constexpr (is_std_array_v<T1>) {
size_t arraySize = array_size_v<T1>; size_t arraySize = array_size_v<T1>;
@ -308,18 +311,21 @@ protected:
} }
} else { } else {
static_assert(std::is_arithmetic_v<sub_array_type>, static_assert(std::is_arithmetic_v<sub_array_type>,
"模板参数T1是std::array类型时它的数组嵌套不能超过两层"); "模板参数T1是std::"
"array类型时它的数组嵌套不能超过两层详见XNDDSInterfac"
"e.cppline 313");
} }
} else { } else {
static_assert(std::is_arithmetic_v<array_type> static_assert(
|| is_std_array_v<array_type>, std::is_arithmetic_v<array_type> || is_std_array_v<array_type>,
"模板参数T1是std::array类型时它的value_" "模板参数T1是std::array类型时它的value_"
"type必须是算术类型或std::array类型"); "type必须是算术类型或std::array类型详见XNDDSInterface.cppline 320");
} }
} }
} else { } else {
static_assert(std::is_arithmetic_v<T1> || is_std_array_v<T1>, static_assert(
"模板参数T1必须是算术类型或std::array类型"); std::is_arithmetic_v<T1> || is_std_array_v<T1>,
"模板参数T1必须是算术类型或std::array类型详见XNDDSInterface.cppline 326");
} }
} }
} }
@ -328,8 +334,10 @@ protected:
void assign_value_set(eprosima::fastcdr::optional<T1> &data, const T2 &model_data) void assign_value_set(eprosima::fastcdr::optional<T1> &data, const T2 &model_data)
{ {
if constexpr (std::is_arithmetic_v<T1>) { if constexpr (std::is_arithmetic_v<T1>) {
static_assert(std::is_arithmetic_v<T2>, "模板参数T2必须是算术类型"); static_assert(std::is_arithmetic_v<T2>,
static_assert(std::is_convertible_v<T2, T1>, "模板参数T2必须可以转换为T1类型"); "模板参数T2必须是算术类型详见XNDDSInterface.cppline 337");
static_assert(std::is_convertible_v<T2, T1>,
"模板参数T2必须可以转换为T1类型详见XNDDSInterface.cppline 339");
data = model_data; data = model_data;
} else if constexpr (is_std_array_v<T1>) { } else if constexpr (is_std_array_v<T1>) {
T1 temp; T1 temp;
@ -347,18 +355,22 @@ protected:
} }
} else { } else {
static_assert(std::is_arithmetic_v<sub_array_type>, static_assert(std::is_arithmetic_v<sub_array_type>,
"模板参数T1是std::array类型时它的数组嵌套不能超过两层"); "模板参数T1是std::"
"array类型时它的数组嵌套不能超过两层详见XNDDSInterface."
"cppline 357");
} }
} else { } else {
static_assert(std::is_arithmetic_v<array_type> || is_std_array_v<array_type>, static_assert(
"模板参数T1是std::array类型时它的value_" std::is_arithmetic_v<array_type> || is_std_array_v<array_type>,
"type必须是算术类型或std::array类型"); "模板参数T1是std::array类型时它的value_"
"type必须是算术类型或std::array类型详见XNDDSInterface.cppline 364");
} }
} }
data = temp; data = temp;
} else { } else {
static_assert(std::is_arithmetic_v<T1> || is_std_array_v<T1>, static_assert(
"模板参数T1必须是算术类型或std::array类型"); std::is_arithmetic_v<T1> || is_std_array_v<T1>,
"模板参数T1必须是算术类型或std::array类型详见XNDDSInterface.cppline 371");
} }
} }

View File

@ -20,7 +20,7 @@ bool XNDDSManager::Initialize()
d->_status = XNFrameObjectStatus::Initialized; d->_status = XNFrameObjectStatus::Initialized;
d->participant_ = nullptr; d->participant_ = nullptr;
d->topics_.clear(); d->topics_.clear();
LOG_INFO("XNDDSManager Initialize Success!"); LOG_INFO("DDS管理器初始化成功!");
return true; return true;
} }
@ -28,7 +28,7 @@ bool XNDDSManager::PrepareForExecute()
{ {
T_D(); T_D();
d->_status = XNFrameObjectStatus::Ready; d->_status = XNFrameObjectStatus::Ready;
LOG_INFO("XNDDSManager is prepared!"); LOG_INFO("DDS管理器准备就绪!");
return true; return true;
} }
@ -40,6 +40,6 @@ void XNDDSManager::SetDomainID(uint32_t domainID)
d->participant_ = FAST_DDS_MACRO::DomainParticipantFactory::get_instance()->create_participant( d->participant_ = FAST_DDS_MACRO::DomainParticipantFactory::get_instance()->create_participant(
domainID, participantQos); domainID, participantQos);
if (d->participant_ == nullptr) { if (d->participant_ == nullptr) {
LOG_ERROR("0x2130 Create DomainParticipant Failed!"); LOG_ERROR("0x2130 DDS管理器创建域参与者失败!");
} }
} }

View File

@ -82,7 +82,7 @@ void XNFramework::SetCpuAffinity(uint32_t cpuAffinity)
bool XNFramework::Initialize(uint32_t initialType) bool XNFramework::Initialize(uint32_t initialType)
{ {
T_D(); T_D();
LOG_INFO("XNFramework Initialize ..."); LOG_INFO("D01054001主框架正在初始化...");
d->ddsManager->SetFramework(XN_THISPTR); d->ddsManager->SetFramework(XN_THISPTR);
d->timeManager->SetFramework(XN_THISPTR); d->timeManager->SetFramework(XN_THISPTR);
d->threadManager->SetFramework(XN_THISPTR); d->threadManager->SetFramework(XN_THISPTR);
@ -92,47 +92,47 @@ bool XNFramework::Initialize(uint32_t initialType)
d->eventManager->SetFramework(XN_THISPTR); d->eventManager->SetFramework(XN_THISPTR);
bool ret = d->eventManager->Initialize(); bool ret = d->eventManager->Initialize();
if (!ret) { if (!ret) {
LOG_ERROR("XNFramework Initialize Failed!"); LOG_ERROR("B01052001主框架初始化失败");
return false; return false;
} }
ret = d->timeManager->Initialize(); ret = d->timeManager->Initialize();
if (!ret) { if (!ret) {
LOG_ERROR("XNFramework Initialize Failed!"); LOG_ERROR("B01052002主框架初始化失败");
return false; return false;
} }
ret = d->ddsManager->Initialize(); ret = d->ddsManager->Initialize();
if (!ret) { if (!ret) {
LOG_ERROR("XNFramework Initialize Failed!"); LOG_ERROR("B01052003主框架初始化失败");
return false; return false;
} }
ret = d->serviceManager->Initialize(); ret = d->serviceManager->Initialize();
if (!ret) { if (!ret) {
LOG_ERROR("XNFramework Initialize Failed!"); LOG_ERROR("B01052004主框架初始化失败");
return false; return false;
} }
ret = d->threadManager->Initialize(); ret = d->threadManager->Initialize();
if (!ret) { if (!ret) {
LOG_ERROR("XNFramework Initialize Failed!"); LOG_ERROR("B01052005主框架初始化失败");
return false; return false;
} }
ret = d->modelManager->Initialize(); ret = d->modelManager->Initialize();
if (!ret) { if (!ret) {
LOG_ERROR("XNFramework Initialize Failed!"); LOG_ERROR("B01052006主框架初始化失败");
return false; return false;
} }
ret = d->scenarioManager->Initialize(); ret = d->scenarioManager->Initialize();
if (!ret) { if (!ret) {
LOG_ERROR("XNFramework Initialize Failed!"); LOG_ERROR("B01052007主框架初始化失败");
return false; return false;
} }
LOG_INFO("XNFramework Initialize Success!"); LOG_INFO("D01054002主框架初始化成功");
LOG_INFO("XNFramework Analyze Scenario Xml ..."); LOG_INFO("D01054003开始解析构型文件 ...");
ret = d->scenarioManager->AnalysisScenarioXml(d->scenarioXml, initialType); ret = d->scenarioManager->AnalysisScenarioXml(d->scenarioXml, initialType);
if (!ret) { if (!ret) {
LOG_ERROR("XNFramework Analyze Scenario Xml Failed!"); LOG_ERROR("B01052008主框架解析构型文件失败");
return false; return false;
} }
LOG_INFO("XNFramework Analyze Scenario Xml Success!"); LOG_INFO("D01054004解析构型文件成功");
return true; return true;
} }

View File

@ -178,46 +178,59 @@ public:
} }
private: private:
// 辅助函数,用于格式化消息 /**
* @brief
* @tparam T
* @param arg
* @return
*/
template <typename T> template <typename T>
static std::string convertToString(const T &arg) static std::string convertToString(const T &arg)
{ {
if constexpr (std::is_arithmetic<T>::value) { if constexpr (std::is_arithmetic_v<T>) {
return std::to_string(arg); // 处理数值类型 return std::to_string(arg); // 处理数值类型
} else { } else if constexpr (std::is_same_v<T, std::string>) {
return arg;
} else if constexpr (std::is_convertible_v<T, std::string>) {
return std::string(arg); return std::string(arg);
} else if constexpr (std::is_same_v<T, char *> || std::is_same_v<T, const char *>) {
return std::string(arg);
} else {
static_assert(std::is_arithmetic_v<T> || std::is_same_v<T, std::string>
|| std::is_convertible_v<T, std::string> || std::is_same_v<T, char *>
|| std::is_same_v<T, const char *>,
"A01021001: 不支持的类型转换详见XNLogger.cppline 199");
} }
} }
// 递归变参函数,用于处理多个参数 /**
template <typename T, typename... Args> * @brief %1%2%3
static std::string formatMessage(const std::string &message, T arg, Args... args) * @tparam Args
* @param message
* @param args
* @return
*/
template <typename... Args>
static std::string formatMessage(const std::string &message, Args &&...args)
{ {
// 查找下一个参数占位符 static_assert(sizeof...(Args) <= 9,
"A01021002: 单条日志参数数量超过限制详见XNLogger.cppline 216");
std::string result = message; std::string result = message;
size_t paramIndex = 0; // 使用初始化列表展开参数包
size_t pos = 0; int index = 1;
// 使用lambda和std::initializer_list展开参数包
// 找到当前参数对应的占位符 (void)std::initializer_list<int>{(
while (true) { [&result, &index](const auto &value) {
std::string placeholder = "%" + std::to_string(paramIndex + 1); std::string placeholder = "%" + std::to_string(index++);
pos = result.find(placeholder); size_t pos = result.find(placeholder);
if (pos != std::string::npos) { if (pos != std::string::npos) {
// 替换占位符使用placeholder的长度 result.replace(pos, placeholder.length(), convertToString(value));
result.replace(pos, placeholder.length(), convertToString(arg)); }
break; }(args),
} 0)...};
paramIndex++; return result;
if (paramIndex > 100) { // 防止无限循环
return result;
}
}
return formatMessage(result, args...);
} }
// 基础情况
static std::string formatMessage(const std::string &message) { return message; }
}; };
/** /**