0

我一直在关注 The Cherno 的游戏引擎系列,但遇到了一个似乎无法解决的问题。到目前为止,这是该系列中唯一我不明白的部分,我在互联网上找到的任何内容都没有帮助。

我们正在创建一个事件系统,其中某些事件(输入、窗口大小调整等)使用从spdlog库构建的日志系统记录到控制台。事件分派器将事件分派给适当的函数:

class EventDispatcher {
    template<typename T>
    using EventFn = std::function<bool(T&)>;
public:
    EventDispatcher(Event& event)
        : m_Event(event) {}

    template<typename T>
    bool Dispatch(EventFn<T> func) {
    if (m_Event.GetEventType() == T::GetStaticType()) {
        m_Event.m_Handled = func(*(T*)&m_Event);
        return true;
    }
    return false;
}
private:
    Event& m_Event;
};

当我构建我的项目时,我得到了错误error C2338: Cannot format argument. To make type T formattable provide a formatter<T> specialization。也许我对 C++ 模板的理解不够好,或者我在滥用库,但我终其一生都无法弄清楚是什么导致了这个错误。我确保我按照这里<fmt/ostream.h>的建议包括在内,但它并没有解决问题。

如果有人知道spdlog并可以帮助我,我将不胜感激。谢谢!

编辑:

完整的输出错误是

1>...\vendor\spdlog\include\spdlog\fmt\bundled\core.h(1568,58): error C2338: Cannot format an argument. To make type T formattable provide a formatter<T> specialization: https://fmt.dev/latest/api.html#udt

它指向第 1568 行spdlog\include\spdlog\fmt\core.h

1563    template <bool IS_PACKED, typename Context, type, typename T,
1564              FMT_ENABLE_IF(IS_PACKED)>
1565    FMT_CONSTEXPR FMT_INLINE auto make_arg(const T& val) -> value<Context> {
1566      const auto& arg = arg_mapper<Context>().map(val);
1567      static_assert(
1568          std::is_same<decltype(arg), const unformattable&>::value, // <-- error
1569          "Cannot format an argument. To make type T formattable provide a "
1570          "formatter<T> specialization: https://fmt.dev/latest/api.html#udt");
1571      return {arg};
1572    }

我知道这并没有真正告诉我们任何事情,但这就是输出控制台给我的全部内容。该文件依赖于解决方案中的其他一些文件,因此我很难提供一个可以轻松运行的示例。抱歉,信息太少了,但任何帮助都会大有帮助。

4

1 回答 1

0

您正在将类型传递给spdlog函数,spdlog但不知道如何格式化它。

例如,如果您尝试执行以下操作,您将收到当前看到的编译错误:

class Person
{ 
public:
    explicit Person( std::string name )
        : name_{ std::move( name ) }
    { }
private:
    std::string name_;
};

int main( )
{
     Person person{ "Bill" };

     // spdlog has no idea how to format a Person object and as 
     // a result this will not compile.
     spdlog::info( "{}", person );
}

如果您想打印自定义类型的内容,可以执行以下操作:

#include "spdlog/fmt/ostr.h"

class Person
{ 
public:
    explicit Person( std::string name )
        : name_{ std::move( name ) }
    { }
    
    // You must overload the insertion operator so that
    // spdlog knows what to do when it encounters a Person.
    template<typename Stream>
    friend Stream& operator<<( Stream& os, const Person& person)
    {
        return os << "Person name: " << person.name_;
    }

private:
    std::string name_;
};

int main( )
{
     Person person{ "Bill" };

     // spdlog now knows how to format a Person object.
     spdlog::info( "{}", person );
}

您显示的内容实际上并未显示您在哪里使用spdlog. 我怀疑它发生在您的事件处理程序中(您传递给的可调用对象Dispatch)。

于 2021-10-05T02:17:12.807 回答