Вместо использования шаблонов классов для признаков в C ++ 11 вы можете использовать объявления функций (определение не требуется). Функции можно найти, используя поиск имени в зависимости от аргумента , так что вы можете специализировать черты для вашего класса в том же пространстве имен, где объявлен ваш класс.
Это полностью устраняет необходимость закрывать пространство имен вашего класса, открывать пространство имен признаков, специализировать черту для вашего класса, используя его полностью определенное имя, закрывать пространство имен признаков, заново открывать пространство имен вашего класса. А также устраняет необходимость включать объявление основного шаблона.
Пример:
#include <type_traits>
template<class T> struct Type {};
template<class T>
void trait_of(Type<T>); // Generic trait version.
namespace N {
struct A;
int trait_of(Type<A>); // Trait specialisation for A.
} // N
int main() {
using trait_of_a = decltype(trait_of(Type<N::A>{})); // trait_of is found using ADL.
static_assert(std::is_same<int, trait_of_a>::value, "");
}
Тип возвращаемого значения функции trait может быть контейнером нескольких типов, например ::1100*.
template<class T>
void more_traits(Type<T>); // Generic trait version. Must be specialized.
namespace N {
struct MoreTraitsOfA {
using type_X = ...;
using type_Y = ...;
};
MoreTraitsOfA more_traits(Type<A>); // Trait specialisation for A.
} // N
using MoreTraits = decltype(more_traits(Type<N::A>{}));
using type_X = MoreTraits::type_X;
using type_Y = MoreTraits::type_Y;