注意:
根据liveworkspace.org的说法,这个问题的答案适用于最新版本的g++(4.7.2),clang(3.2)和icc(13.0.1),但是根据Stephen Lin的评论,它取决于空基类优化和std::tuple
的实现。
原始问题:
如果我有一个模板结构体像这样:
template<
class T1, unsigned short N1,
class T2, unsigned short N2
>
struct ComboThree {
T1 data_1[N1];
T2 data_2[N2];
};
我可以通过专门化来避免零长度数组和额外的对齐填充:
template<class T1, class T2>
struct ComboThree<T1, 0, T2, 0> {
};
template<class T1, class T2, unsigned short N2>
struct ComboThree<T1, 0, T2, N2>
{
T2 data_2[N2];
};
template<class T1, unsigned short N1, class T2>
struct ComboThree<T1, N1, T2, 0>
{
T1 data_1[N1];
};
当TX/NX对中的X变得更大时,像这样专门化变得有些麻烦。在我的项目中,实际的不同组合数量可能会少于五个,因此我最终可能根本不使用模板,但我很好奇:
是否有一种使用模板魔法来避免零长度数组同时又不占用任何额外空间的方法?
例如,这样做:
template<class T, unsigned short N>
struct Array {
T data[N];
};
template<class T>
struct Array<T, 0> {};
template<
class T1, unsigned short N1,
class T2, unsigned short N2
>
struct ComboTwo {
Array<T1, N1> data_1;
Array<T2, N2> data_2;
};
避免使用长度为零的数组,但空结构体需要占用额外的空间。另一方面,下面这种情况:
template<class T, unsigned short N>
struct Array {
T data[N];
};
template<class T>
struct Array<T, 0> {};
template<
class T1, unsigned short N1,
class T2, unsigned short N2
>
struct ComboFour : Array<T1, N1>, Array<T2, N2> {};
看起来做我想要的事情(是吗?),但我不知道如何在我的程序中访问Array<>基本结构中的数据。 Stephen Lin也指出了它的其他限制。
ComboFour
的Array<T, 0>
子对象可能需要零空间,这被称为“空基类优化”,并且是标准允许的,但不是必需的。 - Stephen Lin