2017-02-06 40 views
9

У нас есть следующий метод проверки, является ли наша структура POD или нет. Он всегда возвращает значение:Почему структура с создателем удаленной копии не является типом POD?

bool podTest() { 
    struct podTest { 
    int count; 
    int x[]; 
    }; 

    return std::is_pod<podTest>::value; //Always returns true 
} 

Пока все хорошо. Теперь мы делаем одно изменение и удаляем конструктор копии:

bool podTest() { 
    struct podTest { 
    podTest(const podTest&) = delete; 
    int count; 
    int x[]; 
    }; 

    return std::is_pod<podTest>::value; //Always returns false 
} 

Это всегда возвращает false. Прочитав определение is_pod, я все еще пытаюсь понять, какое требование оно нарушает. Что мне не хватает?

Это составляется на godbolt с использованием GCC 6.1, с -std=c++14

+3

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

+1

@NeilButterworth: Одно из требований типов POD заключается в том, что они тривиально ** копируются. – IInspectable

+1

Как ни странно, 'std :: is_trivially_copyable :: value' возвращает true, поэтому должно быть какое-то другое нарушение требований POD. Конечно, 'int x [];' следует удалить. Если я не ошибаюсь, гибкие границы массива не являются частью C++ 14. – IInspectable

ответ

9

Aha!

Из [класса]:

стручка структуры не является объединением класса, который является как тривиальным классом и класс стандартного макета

, где тривиальный классом является:

тривиальный класс это класс, который является тривиальным копируемыми и имеет один или несколько конструкторов по умолчанию (12.1), все из которых либо тривиальны, либо удалены, и по меньшей мере один из них не удаляется.

Но в [class.copy]:

Если пользователь не объявленная конструктор для класса X, не-явный конструктор, не имеющий никаких параметров неявно объявлен дефолт (8,4).

Ваш podTest, когда вы явно удалили конструктор копирования, не имеет конструктора по умолчанию. Так что это не тривиальный класс, так что это не POD. Если вы добавите:

podTest() = default; 

Тогда это снова станет POD.

+0

@Chuu Извините, это было совершенно неправильно, исправлено. – Barry

+0

Просто добрался, 10 минут слишком поздно. +1 –

+0

Так что в этом случае класс без конструктора копирования может быть скопирован с memcpy()! – Sjoerd

2

Поскольку удаленные копии Конструкторы разрешены для типов POD только после того, как C++ 14. Я бы предположил, что вы компилируете свой код в режиме C++ 11.

+0

«struct» выше тривиально можно скопировать как в C++ 11, так и в C++ 14, и согласно cppr, это все семантика копии, которая нам нужна для POD. –

+3

Мне так странно, что тип noncopyable может быть POD. Я думал, что типы POD должны иметь одинаковое поведение на C и C++. – Brian

+0

@BaummitAugen, это эта страница: http://en.cppreference.com/w/cpp/concept/TriviallyCopyable неправильно? – SergeyA