Выравнивание переменных-членов по типу шаблона - PullRequest
2 голосов
/ 23 декабря 2008

Я хочу выровнять свои переменные-члены на основе типа шаблона класса, но я не уверен, возможно ли это на самом деле.

Ниже приведен (очень) простой пример того, что я хотел бы сделать

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

Итак, возможно ли это на самом деле или выравнивание возможно только с использованием фиксированной постоянной времени компиляции? Если нет, может кто-нибудь придумать способ обойти это?

Спасибо:)

Ответы [ 2 ]

5 голосов
/ 23 декабря 2008

Настраиваемое выравнивание не входит в стандарт, поэтому то, как с ним справляются компиляторы, зависит от них - похоже, 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
  };
};

Это, к сожалению, нарушает POD-сущность MyStruct. Он также не работает со встроенными / существующими типами, поэтому вам придется использовать оболочку для них.

aligned_t<int, 4> myAlignedVariable;
3 голосов
/ 23 декабря 2008

Boost уже решил эту проблему. Они используют технику в boost :: необязательно ( ссылка на заголовок ), которая должна содержать достаточно места для выровненного, произвольного типа, но не может (не будет) создавать экземпляр этот объект на строительстве.

Их решение состояло в том, чтобы выделить простой пул байтов (массив символов) и использовать новые для создания объектов в нужном месте. Адрес, присвоенный на месте new, может иметь произвольное выравнивание.

При этом вы говорите, что приводите очень простой пример в своем вопросе. Какова реальная проблема, которую вы пытаетесь решить, реализуя класс, в котором каждый член имеет указанное пользователем выравнивание, которое не меняется для каждого члена, но может варьироваться для каждого экземпляра класса?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...