我目前正努力将fmt::format_stringto转换为std::string_view。
想法:我想创建一个函数,可以从ISR和任务上下文中调用。但是,在ISR中,不允许动态内存分配。这就是为什么在这种情况下我不能调用fmt::fomat()。但是,我得到了一个奇怪的编译器错误
<source>(67): error C7595: 'fmt::v9::basic_format_string<char>::basic_format_string': call to immediate function is not a constant expression
下面是一个最小的工作示例
#include <fmt/format.h>
#include <string>
#include <string_view>
#include <source_location>
#include <concepts>
#include <cassert>
class DebugQueue
{
public:
bool addToTaskQueue(
std::string& strMessage,
std::string& strCategeory,
const std::source_location loc
)
{
return false;
};
bool addToISRQueue(
const std::string_view strFormatedDebugMessage,
const std::string_view strCategory,
const std::source_location loc)
{
return false;
};
};
class Log
{
public:
template <typename... Args>
bool logAsync(
fmt::format_string<Args...> fmt,
const std::string_view strCategory,
Args&&... args
);
template <typename String_T>
bool logAsync(
String_T& strFormatedDebugMessage,
String_T& strCategory,
const std::source_location loc = std::source_location::current()
);
static bool inHandlerMode();
private:
DebugQueue m_queue;
};
bool Log::inHandlerMode()
{
return false;
}
template<typename ...Args>
bool Log::logAsync(
fmt::format_string<Args...> fmt,
const std::string_view strCategory,
Args&&... args)
{
//if called from ISR we cannot call formatting functions since they will implicitly call new
bool bRes = false;
if (inHandlerMode())
{
fmt::basic_string_view<char> asStringView = fmt;
bRes = logAsync(std::string_view(asStringView.data()), strCategory);
}
else
{
std::string strFormatedMessage = fmt::format(fmt, std::forward<Args>(args)...);
std::string strCat(strCategory);
bRes = logAsync(strFormatedMessage, strCat);
}
}
template<typename String_T>
bool Log::logAsync(
String_T& strFormatedDebugMessage,
String_T& strCategory,
const std::source_location loc)
{
bool bRes = false;
if (inHandlerMode())
{
//called from ISR, do not use any dynamic memory allocation
//just add the unformated message to the queue
bRes = m_queue.addToISRQueue(strFormatedDebugMessage, strCategory, loc);
}
else
{
//called from Task Context
std::string strMsg;
std::string strCat;
if constexpr (std::same_as<std::string, String_T>)
{
std::swap(strMsg, strFormatedDebugMessage);
std::swap(strCategory, strCat);
}
else
{
strMsg = std::string(strFormatedDebugMessage.data());
strCategory = std::string(strCat.data());
}
bRes = m_queue.addToTaskQueue(strFormatedDebugMessage, strCategory, loc);
}
}
static Log g_log;
int main() {
fmt::print("The answer is {}.", 42);
g_log.logAsync("Info {}", "fooCat",1);
g_log.logAsync("Info", "fooCat");
}
https://godbolt.org/z/d7jeTjT6f
谢谢你的帮助,伙计们:)
发布于 2022-11-18 13:21:28
正如@user17732522在注释中所建议的,答案是将String_T&更改为String_T并重命名
template <typename String_T>
bool logAsync(
String_T& strFormatedDebugMessage,
String_T& strCategory,
const std::source_location loc = std::source_location::current()
);
至
template <typename String_T>
bool _logAsync(
String_T& strFormatedDebugMessage,
String_T& strCategory,
const std::source_location loc = std::source_location::current()
);
解决了我的问题。寻求你的帮助:)
https://stackoverflow.com/questions/74476213
复制相似问题