如何专门化模板化类的成员结构

时间:2019-04-26 05:37:23

标签: c++ templates template-specialization

说我有以下模板化的类:

template<typename T>
class Foo {
    struct store_t {
        uint8_t data[];
    } store;
    /// other stuff using T
}

有没有办法构造内部结构的专用版本,该版本等同于以下内容:

class Foo {
    struct store_t {
        uint16_t f1;
        uint16_t f2;
    } store;
    /// other stuff using T
}

我宁愿不使用大多数“其他使用T的东西”。我会专门处理一些访问器。 我觉得我想写点类似的东西

template<>
struct store_t {
    uint16_t f1;
    uint16_t f2;
} Foo<someT>::store;

但是那当然不起作用。

2 个答案:

答案 0 :(得分:6)

与生活中的大多数事情一样,“如何解决模板所遇到的问题”的答案是“使用更多模板”。

解决方案1-将docker-compose写为模板

非常感谢,我们不必做任何疯狂的事情。让我们将store_t之外的store_t编写为模板:

Foo

现在,在编写template<bool use_uint8> struct Foo_store_t { uint8_t data[]; }; template<> struct Foo_store_t<false> { uint16_t f1; uint16_t f2; }; 时,我们可以通过测试一些条件来选择要使用的那个:

Foo

解决方案2-编写两个版本的template<class T> class Foo { constexpr static bool use_uint8 = /* stuff */; using store_t = Foo_store_t<use_uint8>; store_t store; }; ,使用std::conditional

这也是很简单的。 store_t使您可以使用布尔值在两种不同(任意)类型之间进行选择。

std::conditional

这里我使用的是struct store_A { uint8_t data[]; }; struct store_B { uint16_t f1; uint16_t f2; }; class Foo { constexpr static bool useVersionA = /* stuff */; using store_t = std::conditional_t<useVersionA, store_A, store_B>; }; ,它出现在C ++ 14中,但是如果您被限制使用C ++ 11,请执行以下操作:

std::conditional_t

答案 1 :(得分:2)

只是为了好玩,我展示了一种基于自传的另一种可能的解决方案。

假设您想将Foo的类型专门化bool

您可以编写主Foo并添加具有默认值的模板非类型参数(例如,具有默认值bool的{​​{1}})

true

我添加了template <typename T, bool = true> struct Foo { struct store_t { std::uint8_t data[10]; } store; /// other stuff using T T value; }; 作为“使用T的其他内容”的示例。

现在,您可以专门T valueFoo<bool>继承

Foo<bool, false>

这样,您可以专门化template <> struct Foo<bool> : public Foo<bool, false> { struct store_t { std::uint16_t f1, f2; } store; }; / store_t(如果需要,还可以包括其他成员),从store继承“其他使用T的东西”(Foo<bool, false>,例如)。

以下是完整的编译示例

bool value