我想根据类模板类型对齐我的成员变量,但我不确定它是否真的可行。
以下是我想做的一个(非常)简单的例子
template<int Align>
class MyClass
{
private:
struct MyStruct
{
// Some stuff
} __declspec(align(Align));
__declspec(align(Align)) int myAlignedVariable;
};
所以我想要的是Align是一个每个实例的变量,只有这样才能确定类内容的对齐值。
不幸的是我总是收到以下错误
error C2975: 'test::MyClass' : invalid template argument for 'Align', expected compile-time constant expression
那么,这实际上是可行的还是只能使用固定的编译时间常数进行对齐?如果没有,任何人都可以想到解决这个问题吗?
谢谢:)
答案 0 :(得分:5)
自定义对齐不在标准中,因此编译器如何处理它取决于它们 - 看起来VC ++不喜欢将模板与__declspec组合。
我建议使用专业化解决方法,如下所示:
template<int A> struct aligned;
template<> struct aligned<1> { } __declspec(align(1));
template<> struct aligned<2> { } __declspec(align(2));
template<> struct aligned<4> { } __declspec(align(4));
template<> struct aligned<8> { } __declspec(align(8));
template<> struct aligned<16> { } __declspec(align(16));
template<> struct aligned<32> { } __declspec(align(32));
然后从代码中派生出来:
template<int Align>
class MyClass
{
private:
struct MyStruct : aligned<Align> {
// stuff
};
};
这不幸破坏了MyStruct的POD。它也不适用于内置/现有类型,因此您必须使用包装器。
aligned_t<int, 4> myAlignedVariable;
答案 1 :(得分:3)
Boost已经解决了这个问题。他们使用boost::optional(link to header)中的技术,它必须为对齐的任意类型保留足够的空间,但不能(不会)在构造时实际实例化该对象。
他们的解决方案是分配一个简单的字节池(char数组)并使用就地new来在所需位置构造对象。给予就地新的地址可以是任意对齐。
话虽如此,你说你在问题中给出了一个非常简单的例子。您试图通过实现一个类来解决的实际问题是,每个成员都有一个用户指定的对齐方式,每个成员不会因每个成员而异,但每个类实例可能会有所不同?