Let's say I'm writing a trait, and I want to provide out-of-the-box specializations for all the standard library containers.
template <class T>
struct supports_fast_insertion: std::false_type {};
template <class T, class A>
struct supports_fast_insertion<std::list<T, A>>: std::true_type {};
template <class T, class A>
struct supports_fast_insertion<std::forward_list<T, A>>: std::true_type {};
template <class T, class A>
struct supports_fast_insertion<std::unordered_set<T, A>>: std::true_type {};
// ...
This requires #include <list>
, #include <forward_list>
, #include <unordered_set>
, and so on. That means that any file that includes my type trait will also include half of the containers library, which seems sloppy.
If I were only specializing for user-defined types, I could just forward-declare all the ones I care about. But adding declarations to namespace std
– even mere forward declarations – invokes undefined behavior.
Is there a way to avoid the #include
explosion? Is there a conventional way for libraries to handle this?