Ради интереса я покажу еще одно возможное решение, основанное на своего рода наследовании.
Предположим, вы хотите специализироваться Foo
для типа bool
.
Вы можете написать основной Foo
, добавив параметр шаблона нетипичного типа со значением по умолчанию (скажем, bool
со значением по умолчанию true
)
template <typename T, bool = true>
struct Foo
{
struct store_t
{ std::uint8_t data[10]; } store;
/// other stuff using T
T value;
};
Я добавил T value
в качестве примера «других вещей, использующих T».
Теперь вы можете специализироваться Foo<bool>
, наследуя от Foo<bool, false>
template <>
struct Foo<bool> : public Foo<bool, false>
{
struct store_t
{ std::uint16_t f1, f2; } store;
};
Таким образом, вы можете специализировать store_t
/ store
(и других членов, если хотите), наследуя от Foo<bool, false>
"другой материал, использующий T" (a bool value
, например).
Ниже приведен полный пример компиляции
#include <cstdint>
#include <type_traits>
template <typename T, bool = true>
struct Foo
{
struct store_t
{ std::uint8_t data[10]; } store;
T value;
};
template <>
struct Foo<bool> : public Foo<bool, false>
{
struct store_t
{ std::uint16_t f1, f2; } store;
// inherits a bool value from Foo<bool, false>
};
int main()
{
Foo<int> fi;
Foo<bool> fb;
static_assert( std::is_same<decltype(fi.value),
int>::value, "!");
static_assert( std::is_same<decltype(fi.store.data),
std::uint8_t[10]>::value, "!");
static_assert( std::is_same<decltype(fb.value),
bool>::value, "!");
static_assert( std::is_same<decltype(fb.store.f2),
std::uint16_t>::value, "!");
}