'What is the best way to define the same fmt::formatter for multiple types?
I am attempting to write a custom formatter for a Vector<VType>
vector. Depending on build settings, this could be a std::vector
, or a __gnu_debug::vector
. Both these types present an identical external interface, and I would like to format both types identically. Also importantly though, only of of the type types will be properly defined at compile time.
What is the proper way to achieve this? I tried something along the following lines, however it did not result in creation of the formatters I needed.
struct DataClass;
template<>
template<template<typename> typename VectorType>
struct fmt::formatter<VectorType<DataClass>> {
//...
};
Solution 1:[1]
The problem is that std::vector is defined as template<class T, class Allocator = std::allocator<T>> class vector
, so the lookup fails since the formatter is expecting a VectorType
with only 1 template parameter. One solution is to unconstrain the number of template arguments:
template<>
template<template<typename...> typename VectorType>
struct fmt::formatter<VectorType<DataClass>> {
//...
}
I would be interested in a better solution to this problem, since I could easily see this becoming a problem in the future where the formatter is now too unconstrained.
Solution 2:[2]
You could do something like:
#ifdef USE_GNU_DEBUG_VECTOR
template <typename T>
using Vector = __gnu_debug::vector<T>;
#else
template <typename T>
using Vector = std::vector<T>;
#endif
template <typename T>
struct fmt::formatter<Vector<T>> {
//...
};
where USE_GNU_DEBUG_VECTOR
is controlled by your build settings.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Chuu |
Solution 2 | vitaut |