Closed cuppajoeman closed 5 months ago
Have you tried another sample?
#include <iterator>
#include "spdlog/spdlog.h"
#include "spdlog/fmt/ostr.h" // must be included
#include "spdlog/sinks/stdout_sinks.h"
class some_class {
int code;
};
template<typename OStream>
friend OStream &operator<<(OStream &os, const some_class& to_log)
{
fmt::format_to(std::ostream_iterator<char>(os), "{:04X}", to_log.code);
return os;
}
void custom_class_example()
{
some_class c; c.code = 17;
auto console = spdlog::stdout_logger_mt("console");
console->info("custom class with operator<< using fmt: {}..", c);
}
Also, did you check the link to the official fmt documentation (https://fmt.dev/latest/api.html#udt) in the error message?
Have you tried another sample?
#include <iterator> #include "spdlog/spdlog.h" #include "spdlog/fmt/ostr.h" // must be included #include "spdlog/sinks/stdout_sinks.h" class some_class { int code; }; template<typename OStream> friend OStream &operator<<(OStream &os, const some_class& to_log) { fmt::format_to(std::ostream_iterator<char>(os), "{:04X}", to_log.code); return os; } void custom_class_example() { some_class c; c.code = 17; auto console = spdlog::stdout_logger_mt("console"); console->info("custom class with operator<< using fmt: {}..", c); }
Also, did you check the link to the official fmt documentation (https://fmt.dev/latest/api.html#udt) in the error message?
I tried the example you provided which also errors out the same way. I'm using
CMakeLists.txt
:
cmake_minimum_required(VERSION 3.10)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # allows for language servers to understand the codebase
set(CMAKE_LINKER_TYPE MOLD) # use a modern linker
project(MyProject)
# Specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# Add spdlog directory
add_subdirectory(external_libraries/spdlog)
# include_directories(external_libraries/spdlog/include)
# Add executable
add_executable(MyProject main.cpp)
# Link spdlog
target_link_libraries(MyProject PRIVATE spdlog::spdlog)
I looked at the fmt documentation. Note that my question issue is in relation to the first example which has the following language:
Due to the usage of "or" here I assumed that the first example wouldn't have to do anything much with fmt
.
Either way let me know if you see any incorrect usage of spdlog
or if this is an actual problem.
I noticed that this is a breaking change in fmt version 10 (fmtlib/fmt#3318). The Wiki example seems to be out of date.
The following changes should work, please try it.
#include "spdlog/spdlog.h"
#include "spdlog/fmt/ostr.h" // must be included
#include "spdlog/sinks/stdout_sinks.h"
class some_class {};
std::ostream& operator<<(std::ostream& os, const some_class& c)
{
return os << "some_class";
}
+
+template <> struct fmt::formatter<some_class> : fmt::ostream_formatter {};
void custom_class_example()
{
some_class c;
auto console = spdlog::stdout_logger_mt("console");
console->info("custom class with operator<<: {}..", c);
}
+template <> struct fmt::formatter<some_class> : fmt::ostream_formatter {};
Hi, I got the same compile issue, and fixed with this change in my case, thank you so much!
Just writing this to confirm that the newest information in the docs fixes it
Can I create a template out of the, uh, template fix?
I assumed
template <typename T> struct formatter<T>: ostream_formatter{};
would work, but it doesn't. I'm sick of having to append it to every custom class.
@harryjwright This feature is provided by fmt. Please ask in the fmt repository.
[!Tip] From the latest documentation, it seems that
fmt::formatter<T>
can define several types of formats withstd::enable_if_t
: https://fmt.dev/11.0/api/#formatting-user-defined-types
In the quickstart page 1, we have:
building this example yields the following error: