Почему нет признака типа std:: is struct?
Я видел, что для того, чтобы проверить, если тип T
это класс, который я могу использовать:
bool isClass = std::is_class<T>::value;
возвращает true для обоих классов и структур. Я знаю, что в C++ они почти одно и то же, но я хотел бы знать, почему нет различия между ними в черте типа. Всегда ли бесполезно проверять эту разницу, или есть еще какая-то причина, которую я не понимаю?
5 ответов:
возвращает true для обоих классов и структур. Я знаю, что в C++ они почти одно и то же, но я хотел бы знать, почему нет различия между ними в черте типа.
к сожалению это распространенное заблуждение в C++. Иногда это происходит из-за фундаментального непонимания, но в других случаях это происходит из-за двусмысленности в английском языке. Это может исходить из неточной диагностики компилятора, плохо написанных книг, неправильных так ответы...
Вы, наверное, читали что-то вроде этого:
" в C++ нет разницы между структурой и классом, за исключением видимости по умолчанию членов и баз."
этот отрывок может быть истолкован в смысле, который вводит в заблуждение, потому что понятия личность и равенство трудно отличить при использовании фраз, таких как "нет разницы".
в самом деле, в C++ не имеет структуры, начиная с 1985 года. Оно есть только классы.
тип типов, которые вы объявляете с ключевым словом
class
и ключевое словоstruct
are классы. Период. Ключевое словоstruct
, и правила видимости, которые являются по умолчанию при определении класса с использованием этого ключевого слова, были сохранены только для обратной совместимости с C ... но это синтаксическая вещь. Это не делает полученные типы На самом деле быть другого рода.тип признака не делает никакого различия, потому что там буквально не тот, чтобы сделать.
невозможно различить разницу в семантике для пустых определений типа
class C { public: };
С
struct S { };
или же
class C { };
и
struct S { private: };
помимо
struct
vsclass
ключевое слово, нет никакой поведенческой разницы прощупывается. Смотрите также это Q & A.Примечание: как заметил @KyleStrand, Деривация также требует явных спецификаторов доступа, поэтому
S : private Base {};
иC : Base {};
эквивалентны, то же самое, чтоS : Base {};
иC : public Base {};
, гдеS
- это структура,C
- это класс, иBase
может быть.
Это одно и то же. Единственное различие (видимость элемента по умолчанию) существует только во время компиляции. В противном случае нет никакой разницы между
struct
иclass
.ETA: что вы, вероятно, хотите-это
std::is_pod
, который скажет вам, является ли ваш класс "простым старым типом данных". Большая часть обсуждений и комментариев по этому вопросу, по-видимому, указывает на то, что именно этого хотят те, кто считает, что должно быть различие.
Другие правильно указали, что в C++ ключевые слова
struct
иclass
имеют то же значение, за исключением разницы в видимости членов.вызываете ли вы агрегатные типы, определенные таким образом" структуры "или" классы "или" weiruewzewiruz", зависит от вас. В интересах коммуникации, как правило, рекомендуется следовать установленным конвенциям, поэтому я бы посоветовал не "weiruewzewiruz".
также рекомендуется использовать семантические различия в качестве руководство по выбору слов. Использование
struct
является более распространенным для простых агрегированных данных, которые не имеют много внутренней логики и инвариантов; типичное использование было быstruct point { float x; float y; };
. Такие типы часто называют "структурами" или "структурами" в литературе. Было бы не удивительно, если кто-то используетfprintf
в C++ первый аргумент называется "указатель на файловую структуру". Файл является примером того, что Скотт Мейерс означает в "более эффективном C++", пункт 34:это безопасно предположить, что определение структуры, которое компилируется в обоих языки С и C++ -С. а.с] выкладывается таким же образом, как компиляторы.
Что касается языка программирования, то не имеет значения, если определение c++ агрегата данных в вопрос использовал ключевое слово
struct
илиclass
(со спецификатором общего доступа).struct
- Это, пожалуй, более естественным выбором, потому что семантику C++ в совокупности составляют семантику с ключевого слова struct. Кроме того, используяstruct
позволяет источникам C и c++ легче совместно использовать одно определение типа.стандарт C++ использует "struct" и "structure" как на естественном, так и на языке программирования, а не только в случаях совместимости: 1.7/5: "структура, объявленная как", или 3.2/4
struct X; // declare X as a struct type
. Наиболее интересным является 9/8, закладывающий основу для взаимодействия-критерии:8 структура стандартной компоновки-это класс стандартной компоновки определиться с классом-ключевые структуры или класса-ключ класс. [...]
как кто-нибудь, читающий это, может утверждать, что в C++ нет структур, вне меня. Это явно не ошибка редактирования, потому что термины "структура" и "класс" явно заданы по отношению друг к другу.
интереснее, чем выбор слов и вопросы вкуса, однако, являются очевидными, проверяемыми различиями. При каких обстоятельствах агрегат C++ сопоставим и совместим с C
struct
? Возможно, этот вопрос лежал в основе вашего вопроса? Типовая форма стандарта, упомянутая в цитате, является критерием. Он подробно описан в 9/7 и по существу предписывает, что
- только один класс в иерархии наследования может иметь нестатические определения элементов данных (вероятно, потому, что стандарт не имеет требуется указать порядок элементов данных, определенных на разных уровнях в такой иерархии);
- виртуальные функции или виртуальные базовые классы не допускаются (из-за дополнительных данных экземпляра, необходимых для информации о времени выполнения);
- все члены имеют одинаковый "контроль доступа" (либо публичный, защищенный или частный; вероятно, потому, что реализация может свободно заказывать контроль доступа).
стандарт тогда говорит
9 [ Примечание: классы стандартной компоновки полезны для общения с кодом, написанным на других языках программирования. Их расположение указано в 9.2.-конец Примечание ]
конечно, определение структуры, которое компилируется в C, удовлетворяет этим критериям, следовательно, утверждение Скотта Мейерса.
FILE
от stdio.h-яркий, не совсем тривиальный пример. Обратите внимание, что стандарт не дает гарантий, поскольку макет объекта зависит от реализации и может изменяться только с помощью параметр компилятора.имеет ли класс стандартную компоновку, можно проверить с помощью признака типа
std::is_standard_layout<T>
. Следующая программа, которая вдохновлена пример на cppreference, проверяет основные случаи, изложенные в стандарте.#include <cstdio> #include <typeinfo> #include <type_traits> using namespace std; struct funcOnlyT // fine { int f(); }; class podT { // "class" is ok int m1; int m2; }; struct badAccessCtrlT { // bad: public/private int m1; private: int m2; }; struct polymorphicT { // bad: polymorphic int m1; int m2; virtual void foo(); }; struct inheritOkT: podT // ok: inheritance, data only on one level { int f(); }; struct inheritPlusDataT: podT // bad: inheritance, data on 2 levels { int m3; }; template<typename T1, typename T2> struct templT // ok with std layout types T1, T2 { T1 m1; T2 m2; }; // print type "name" and whether it's std layout template<typename T> void printIsStdLayout() { printf("%-20s: %s\n", typeid(T).name(), std::is_standard_layout<T>::value ? "is std layout" : "is NOT std layout"); } int main() { printIsStdLayout<funcOnlyT>(); printIsStdLayout<podT>(); printIsStdLayout<badAccessCtrlT>(); printIsStdLayout<polymorphicT>(); printIsStdLayout<inheritOkT>(); printIsStdLayout<inheritPlusDataT>(); printIsStdLayout<templT<int, float> >(); printIsStdLayout<FILE>(); }
пример:
$ g++ -std=c++11 -Wall -o isstdlayout isstdlayout.cpp && ./isstdlayout 9funcOnlyT : is std layout 4podT : is std layout 14badAccessCtrlT : is NOT std layout 12polymorphicT : is NOT std layout 10inheritOkT : is std layout 16inheritPlusDataT : is NOT std layout 6templTIifE : is std layout 9__sFILE64 : is std layout
C++11 §9/8 ([класса]/8):C++11 §9/10 ([класса]/10):" A структура стандартной компоновки-это класс стандартной компоновки, определенный с помощью class-key
struct
или class-keyclass
. А объединение стандартных макетов-это класс стандартной компоновки, определенный с помощью class-keyunion
." A POD struct является несоюзным классом, который является как тривиальным классом, так и классом стандартной компоновки и не имеет нестатические элементы данных типа non-POD struct, non-POD union (или массив таких типов). [...]
С a POD struct является классом стандартной компоновки это подмножество структура стандартной компоновки. насколько я знаю это самое общее значение struct в стандарте C++. И поэтому, по-видимому, то, что вы ищете, - это признак типа или набор признаков типа, который позволяет вам идентифицировать структура стандартной компоновки как таковой.
и вуаля, глядя на список черт типа есть
is_class
иis_standard_layout
. Когда тип satisifies 1both это "структура". Или точнее, это структура стандартной компоновки, как определено C++11 §9/8.
о
" я хотел бы знать, почему нет различия между [class и struct] в типе признака
Ну, нет. Вот это
is_standard_layout
черта.
о
" всегда ли бесполезно проверять эту разницу, или есть еще какая-то причина, которую я не понимаю?
нет, это не бесполезно проверять эту разницу. Стандарт определяет стандартные-макета по той причине, что это очень практически полезным. Как отмечает сам стандарт,
C++11 §9/9 ([класса]/9):" [Примечание: классы стандартной компоновки полезны для связи с кодом, написанным на других языках программирования. Их расположение указано в 9.2.- Конечная нота ]
Примечания:
1 Theis_class
черта истинна дляclass
илиstruct
, а неunion
, хотя стандарт определяет, что "профсоюз-это класс". Т. е. признак более специфичен, чем общая терминология.