Изначально у меня есть набор некоторых признаков StandardInfo и вспомогательный шаблон оболочки StandardTraits, полный статических методов, которые делают что-то с StandardInfo:
#include <iostream>
#include <type_traits>
#include <cstdint>
template <std::uint32_t Id>
struct StandardInfo
{ };
template <>
struct StandardInfo<1>
{
using Field1 = std::integral_constant<std::uint32_t, 42>;
};
template <>
struct StandardInfo<2>
{
using Field1 = std::integral_constant<std::uint32_t, 19>;
};
// and more StandardInfo specifications...
template <std::uint32_t Id>
struct StandardTraits
{
using Info = StandardInfo<Id>;
static void DoFoo() { std::cout << Info::Field1::value; }
};
int main()
{
StandardTraits<1>::DoFoo();
return 0;
}
Предположим, мне нужно ввести еще одну черту нестандартного типа.Все специализации StandardInfo генерируются автоматически, и я не должен менять этот порядок вещей.Поэтому я должен представить черту NonStandartInfo.Поэтому мне нужна оболочка NonStandardTraits, содержащая те же методы, что и в StandardTraits.Оказывается, что StandardTraits и NonStandardTraits отличаются только псевдонимом типа Info.Копирование-вставка реализации кажется сомнительным, поэтому мне кажется, что мне нужно осуществить реализацию оболочки в виде TraitsImpl, а не изменять существующий код, который уже использует StandardTraits.
#include <iostream>
#include <type_traits>
#include <cstdint>
template <std::uint32_t Id>
struct StandardInfo
{ };
template <>
struct StandardInfo<1>
{
using Field1 = std::integral_constant<std::uint32_t, 42>;
};
template <>
struct StandardInfo<2>
{
using Field1 = std::integral_constant<std::uint32_t, 19>;
};
// and more StandardInfo specifications...
template <std::uint32_t Id>
struct NonStandardInfo
{ };
template <>
struct NonStandardInfo<1>
{
using Field1 = std::integral_constant<int, -1>;
};
template <>
struct NonStandardInfo<2>
{
using Field1 = std::integral_constant<int, -2>;
};
template <typename Info>
struct TraitsImpl
{
static void DoFoo() { std::cout << Info::Field1::value; }
};
template <std::uint32_t Id>
struct StandardTraits: TraitsImpl<StandardInfo<Id> >
{
};
template <std::uint32_t Id>
struct NonStandardTraits: TraitsImpl<NonStandardInfo<Id> >
{
};
int main()
{
StandardTraits<1>::DoFoo();
NonStandardTraits<1>::DoFoo();
return 0;
}
Но не раскрывает ли детали реализации (через публичное наследование)?Наследование частных и прокси-вызовов также выглядит глупо.Есть ли более элегантный подход?