按模板类型对齐成员变量

问题描述 投票:0回答:3

我想根据类模板类型对齐我的成员变量,但我不确定这是否真的可行。

以下是我想做的一个(非常)简单的示例

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

那么,这实际上可能吗,还是只能使用固定的编译时间常数才能实现对齐?如果没有的话,有人能想办法解决这个问题吗?

谢谢:)

c++ templates
3个回答
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;

3
投票

Boost已经解决了这个问题。他们使用了boost::Optional链接到标题)中的技术,该技术必须为对齐的任意类型保留足够的空间,但不能(不会)在构造时实际实例化该对象。

他们的解决方案是分配一个简单的字节池(字符数组)并使用就地 new 在所需位置构造对象。赋予 in-place new 的地址可以是任意对齐的。

话虽这么说,你是说你在问题中给出了一个非常简单的例子。您试图通过实现一个类来解决的实际问题是什么,其中每个成员都有用户指定的对齐方式,该对齐方式不会因成员而异,但可以因类实例而异?


0
投票

从C++14开始,C++支持此功能。

template <typename T>
struct __declspec(align(16)) type_a {
    T* c;
};

template <typename T>
struct type_b {
    T* c;
};

int main() {
    static_assert(sizeof(type_a<int>) == 16);
    static_assert(sizeof(type_b<int>) == 8);
}
© www.soinside.com 2019 - 2024. All rights reserved.