Могу ли я использовать static_assert без предоставления реального параметра шаблона? - PullRequest
0 голосов
/ 27 января 2011
template<typename T>
class MyClass
{
......
private:
    union u_
    {
        struct m_
        {
            int i1;
            int i2;
            int i3;
        } m;
        char data[SIZE]; // convenience buffer for serialization/deserialization;
    } u;
    T container;
......
};

Чтобы иметь возможность сериализовать / десериализовать объект MyClass, я использую объединение, чтобы объединить свои поля данных, и использую буфер data , чтобы сделать это оптом.Я хочу убедиться, что данные достаточно велики для сбора элементов данных на случай, если кто-то расширит их в будущем, поэтому я добавил это статическое утверждение.

static_assert(sizeof(MyClass<int>::u_::data) >= sizeof(MyClass<int>::u_::m_));

У этого подхода есть две проблемы.Во-первых, компилятор жалуется, что объединение не является публичным.Во-вторых, это должно сохраняться для любого контейнера типа T, поэтому я не хочу быть конкретным, но давать int как фиктивный тип не получится, но я не хочу вводить другой тип только для статического утвержденияЕсть ли способ использовать фиктивный тип здесь?

Есть ли более элегантное решение?

EDIT : Джеймс, спасибо за то, что поднял вопрос о переносимости.Порядковый номер и выравнивание являются законными проблемами, но в моем случае сериализация / десериализация происходит локально, так что все в порядке.

Ответы [ 3 ]

1 голос
/ 27 января 2011
char data[SIZE]; 

Вместо этого вы можете сделать следующее:

char data[sizeof(m_)]; 

Это всегда будет удовлетворять условию в этом static_assert:

static_assert(sizeof(MyClass<int>::u_::data) >= sizeof(MyClass<int>::u_::m_));

Так как оно будетвсегда удовлетворяй, несмотря ни на что, тебе не даже нужно написать static_assert!

1 голос
/ 27 января 2011

Есть ли более элегантное решение?

Почему бы просто не интерпретировать структуру как массив char?

struct m_
{
    int i1;
    int i2;
    int i3;
};

// ...
m_ m;
char* data = static_cast<char*>(static_cast<void*>(&m));

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

0 голосов
/ 27 января 2011

Чтобы решить проблему private, вы можете поместить static_assert где-нибудь внутри класса, например, в конструктор или статический метод.

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