2015-08-04 4 views
5

Мне просто интересно ... Предположим, у меня есть структура POD на C++. Если бы я поставил static_assert там, это испортит факт, что это POD?Будет ли static_assert в POD разрушать POD?

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

Другими словами (более конкретные):

#include <iostream> 
#include <type_traits> 

struct A 
{ 
    void* ptr; 

    static_assert(sizeof(void*) == 8, "Pointer should have size 8; platform unsupported"); 
}; 

int main() 
{ 
    // Is it guaranteed that this will evaluate to 'true'? 
    std::cout << std::is_pod<A>::value << std::endl; 
} 
+7

Я считаю, что нет, 'static_assert' умирает на время компиляции, я не думаю, что это даже включено в результате двоичном .. У меня нет стандарта рядом со мной, чтобы получить точный ответ –

+0

я думаю' станд :: is_pod' действительно не может быть ошибкой. – Quentin

+0

@DavidHaim Конечно, это точка 'static_assert'. По-прежнему afaik не определяется, как его реализовать, поэтому, если он будет генерировать виртуальный член для выполнения своей работы, он теоретически может испортить 'is_pod'. (Не то, чтобы я мог понять, почему это так, но это еще одна история ...) Правильно? – atlaste

ответ

4

В C++ 11 типа считается POD, если это

  • trivial (скаляр типа, тривиальные копируемый класс с тривиальным конструктором по умолчанию, или массив такого типа/класса)
  • standard layout (не имеет виртуальные функции, ни виртуальных базовых классов и т.д.)

В принципе ничего, что препятствовало бы копирование объектов, как будто они только составляют сырые байт.

static_assert s есть, чтобы проверить что-то во время компиляции и не изменять макет объекта или тривиальность (или его отсутствие) при построении, копировании и т. Д. Объекта. Следовательно, добавление любого количества статических утверждений к типу (struct/class) не должно изменять его POD-версию.

Вы можете проверить, рассматривает ли компилятор тип POD, используя std::is_pod<T>::value. Это не изменилось бы до и после добавления static_assert s к нему.

Это все, что говорится в стандарте относительно static_assert. Из [dcl.dcl]:

В static_assert декларированиепостоянная выражения должна быть постоянным выражением, которое может быть преобразовано в контекстуально bool. Если значение выражения, когда оно преобразуется, истинно, декларация не действует. В противном случае программа плохо сформирована, и в результате диагностическое сообщение (1.4) должно содержать текст строкового литерала, за исключением того, что в диагностическом сообщении не должны появляться символы, не содержащиеся в базовом наборе символов источника (2.3).

+0

Несомненно, обе они также оцениваются во время компиляции, но у afaik нет ограничений на реализацию в std, которые запрещают им добавлять виртуальную функцию, тем самым нарушая ограничения POD, правильно? – atlaste

+1

Тривиальная часть имеет ограничение на то, что класс не должен иметь виртуальной функции. Если это не тривиально, это не POD. – legends2k

+3

@atlaste: Я не помню явный запрет (который потребует проверки всего стандарта), но я считаю, что существует широкий консенсус в отношении того, что компиляторы не могут добавлять виртуальные функции только потому, что им это нравится. Единственными способами добавить виртуальную функцию в соответствии со стандартом является объявление одного или наследование. (IOW, консенсус в том, что это исчерпывающий список) – MSalters

Смежные вопросы