'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