首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >c++转换fmt::format_string<Args...>to std::string_view

c++转换fmt::format_string<Args...>to std::string_view
EN

Stack Overflow用户
提问于 2022-11-17 13:22:04
回答 1查看 71关注 0票数 2

我目前正努力将fmt::format_stringto转换为std::string_view。

想法:我想创建一个函数,可以从ISR和任务上下文中调用。但是,在ISR中,不允许动态内存分配。这就是为什么在这种情况下我不能调用fmt::fomat()。但是,我得到了一个奇怪的编译器错误

代码语言:javascript
运行
复制
<source>(67): error C7595: 'fmt::v9::basic_format_string<char>::basic_format_string': call to immediate function is not a constant expression

下面是一个最小的工作示例

代码语言:javascript
运行
复制
#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

谢谢你的帮助,伙计们:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-18 13:21:28

正如@user17732522在注释中所建议的,答案是将String_T&更改为String_T并重命名

代码语言:javascript
运行
复制
template <typename String_T>
    bool logAsync(
      String_T& strFormatedDebugMessage,
      String_T& strCategory,
      const std::source_location loc = std::source_location::current()
    );

代码语言:javascript
运行
复制
template <typename String_T>
    bool _logAsync(
      String_T& strFormatedDebugMessage,
      String_T& strCategory,
      const std::source_location loc = std::source_location::current()
    );

解决了我的问题。寻求你的帮助:)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74476213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档