我有一个类,看起来像这样:

class Compound
{
    void* pValue0;
    void* pValue1;
    void* pValue2;
    void* pValue3;
    void* pValue4;
    void* pValue5;
    void* pValue6;
    void* pValue7;
    void* pValue8;
    void* pValue9;
    void* pValueA;
    void* pValueB;
    void* pValueC;
};

当我创建一个新的Compound类时,我分配了额外的内存[sizeof(Compound)+ extraSpace]。每个pValue都引用额外内存中的地址。

现在,我想根据需要减少pValue的数量。模板似乎很合适。

因此,如果我想要类Compound ,则只需要pValue0和pValueA,然后让编译器删除所有其他pValues。本质上,我希望它成为:
template <uint Mask = 0A>
class Compound<Mask>
{
    void* pValue0;
    void* pValueA;
}

这可能吗?我与enable_if关系密切,但是当我尝试将其限制为特定掩码时,当enable_if情况为false时,编译器会引发有关无法找到类型的错误。

谢谢你们!

最佳答案

这可能会做:

template<char...>
struct flags_tag {constexpr flags_tag(){}; };

template<char...Cs>
struct make_flags{ using type=flags_tag<Cs...>; };
template<char...Cs>
struct make_flags<'0','x',Cs...>:make_flags<Cs...>{};
template<char...Cs>
struct make_flags<'0','X',Cs...>:make_flags<Cs...>{};
template<char...Cs>
using make_flags_t = typename make_flags<Cs...>::type;

template<char...Cs>
constexpr make_flags_t<Cs...> operator""_flag(){ return {}; }

template<char> struct pValue_t;
template<> struct pValue_t<'0'>{ void* pValue0 = 0; };
template<> struct pValue_t<'1'>{ void* pValue1 = 0; };
// ...
template<> struct pValue_t<'A'>{ void* pValueA = 0; };
template<> struct pValue_t<'B'>{ void* pValueB = 0; };
template<> struct pValue_t<'C'>{ void* pValueC = 0; };

template<class flags>
struct Compound;

template<char...Cs>
struct Compound< flags_tag<Cs...> >:
  pValue_t<Cs>...
{};

然后,您可以像这样使用它:
using my_type = Compound< decltype( 0x0A_flag ) >;
int main() {
  my_type test;
  std::cout << test.pValue0 << test.pValueA << '\n';
}

这似乎在做你想要的。

我还将禁用Compound类型的复制/移动ctor,并使用private工厂功能将其其他构造函数friend设置为。

请注意,此代码可以生成指数级的类(2 ^ 12或4k),并且可能导致二进制膨胀(如果没有内联的每类代码)。

[现场示例]

09-25 19:16