Почему C ++ не имеет отражения?


337

Это несколько странный вопрос. Мои цели - понять решение по проектированию языка и определить возможности отражения в C ++.

  1. Почему комитет по языку C ++ не пошел на реализацию рефлексии на языке? Является ли отражение слишком сложным в языке, который не работает на виртуальной машине (например, Java)?

  2. Если кто-то реализует рефлексию для C ++, какие будут проблемы?

Я думаю, что использование отражений хорошо известно: редакторы могут быть написаны легче, программный код будет меньше, макеты могут генерироваться для модульных тестов и так далее. Но было бы здорово, если бы вы тоже могли прокомментировать использование рефлексии.

Ответы:


631

Есть несколько проблем с отражением в C ++.

  • Нужно добавить много работы, и комитет C ++ довольно консервативен и не тратит время на радикально новые функции, если они не уверены, что он окупится. (Было предложено добавить систему модулей, аналогичную сборкам .NET, и, хотя я думаю, что существует общее мнение, что было бы неплохо иметь это, это не является их главным приоритетом в настоящее время, и было отложено до C ++ 0x. Мотивация для этой функции - избавиться от #includeсистемы, но она также включит по крайней мере некоторые метаданные).

  • Вы не платите за то, что не используете. Это одна из основных принципов проектирования, лежащих в основе C ++. Почему мой код должен содержать метаданные, если они мне могут никогда не понадобиться? Кроме того, добавление метаданных может помешать компилятору оптимизировать. Зачем мне платить эту стоимость в моем коде, если мне никогда не понадобятся эти метаданные?

  • Что приводит нас к другому важному моменту: C ++ дает очень мало гарантий относительно скомпилированного кода. Компилятору разрешено делать практически все, что ему нравится, при условии, что полученная функциональность соответствует ожидаемой. Например, ваши классы не обязательно должны быть там . Компилятор может оптимизировать их, встроить все, что они делают, и он часто делает именно это, потому что даже простой код шаблона имеет тенденцию создавать довольно много экземпляров шаблона. Стандартная библиотека C ++ опирается на эту агрессивную оптимизацию. Функторы являются эффективными, только если можно оптимизировать накладные расходы на создание и уничтожение объекта. operator[]по вектору сравнимо только с производительностью индексации массивов, поскольку весь оператор может быть встроен и, таким образом, полностью удален из скомпилированного кода. C # и Java дают много гарантий о выводе компилятора. Если я определю класс в C #, то этот класс будет существовать в результирующей сборке. Даже если я никогда не использую это. Даже если все вызовы его функций-членов могут быть встроены. Класс должен быть там, чтобы рефлексия могла его найти. Частично это облегчается компиляцией C # в байт-код, что означает, что JIT-компилятор можетудаляйте определения классов и встроенные функции, если хотите, даже если исходный компилятор C # не может. В C ++ у вас есть только один компилятор, и он должен выводить эффективный код. Если бы вам было позволено проверять метаданные исполняемого файла C ++, вы ожидали бы увидеть каждый класс, который он определил, а это значит, что компилятор должен будет сохранить все определенные классы, даже если они не нужны.

  • И тогда есть шаблоны. Шаблоны в C ++ не похожи на шаблоны в других языках. Каждый экземпляр шаблона создает новый тип. std::vector<int>это совершенно отдельный класс от std::vector<float>. Это добавляет много разных типов во всей программе. Что должно увидеть наше отражение? Шаблон std::vector ? Но как это может быть, поскольку это конструкция с исходным кодом, которая не имеет смысла во время выполнения? Надо бы увидеть отдельные классы std::vector<int>и std::vector<float>. А std::vector<int>::iteratorи std::vector<float>::iterator, то же самое дляconst_iteratorи так далее. И как только вы вступаете в метапрограммирование шаблонов, вы быстро заканчиваете создание сотен шаблонов, каждый из которых снова вставляется и удаляется компилятором. Они не имеют никакого значения, кроме как как часть метапрограммы времени компиляции. Должны ли все эти сотни классов быть видимыми для размышления? Им придется это сделать, потому что иначе наше отражение будет бесполезным, если оно даже не гарантирует, что классы, которые я определил, действительно будут там . И побочной проблемой является то, что класс шаблона не существует, пока он не будет создан. Представьте себе программу, которая использует std::vector<int>. Должна ли наша система отражения видеть std::vector<int>::iterator? С одной стороны, вы, конечно, ожидаете этого. Это важный класс, и он определяется с точки зрения std::vector<int>, который делаетсуществуют в метаданных. С другой стороны, если программа на самом деле никогда не использует этот шаблон класса итератора, его тип никогда не будет создан, и поэтому компилятор не будет генерировать класс в первую очередь. И уже слишком поздно создавать его во время выполнения, так как для этого требуется доступ к исходному коду.

  • И, наконец, рефлексия не так важна в C ++, как в C #. Причина снова в шаблонном метапрограммировании. Он не может решить все, но во многих случаях, когда вы иначе прибегаете к рефлексии, можно написать метапрограмму, которая делает то же самое во время компиляции. boost::type_traitsпростой пример. Вы хотите знать о типе T? Проверьте его type_traits. В C # вам придется ловить рыбу после его типа, используя отражение. Отражение все еще было бы полезно для некоторых вещей (основное использование, которое я вижу, которое метапрограммирование не может легко заменить, для автоматически сгенерированного кода сериализации), но это будет нести некоторые значительные затраты для C ++, и это просто не нужно так часто, как есть на других языках.

Изменить: В ответ на комментарии:

cdleary: Да, символы отладки делают нечто подобное в том смысле, что они хранят метаданные о типах, используемых в исполняемом файле. Но они также страдают от проблем, которые я описал. Если вы когда-нибудь пытались отладить сборку релиза, вы поймете, что я имею в виду. Существуют большие логические пробелы, когда вы создали класс в исходном коде, который был выделен в конечном коде. Если бы вы использовали рефлексию для чего-то полезного, вам нужно, чтобы оно было более надежным и последовательным. Как таковые, типы будут исчезать и исчезать почти каждый раз, когда вы компилируете. Вы меняете крошечную деталь, и компилятор решает изменить, какие типы будут встроенными, а какие нет, как ответ. Как извлечь из этого что-нибудь полезное, когда вы даже не гарантируется, что наиболее важные типы будут представлены в ваших метаданных? Тип, который вы искали, возможно, был там в последней сборке, но теперь его нет. А завтра кто-нибудь проверит небольшое невинное изменение на маленькую невинную функцию, которая делает тип достаточно большим, чтобы он не стал полностью встроенным, поэтому он вернется снова. Это все еще полезно для отладочных символов, но не намного больше этого. Я бы не хотел пытаться генерировать код сериализации для класса в соответствии с этими условиями. но не намного больше чем это. Я бы не хотел пытаться генерировать код сериализации для класса в соответствии с этими условиями. но не намного больше чем это. Я бы не хотел пытаться генерировать код сериализации для класса в соответствии с этими условиями.

Эван Теран: Конечно, эти проблемы могут быть решены. Но это возвращается к моей точке № 1. Это заняло бы много работы, и у комитета C ++ есть много вещей, которые они считают более важными. Является ли выгода от того, что какое-то ограниченное отражение (и оно будет ограничено) в C ++ действительно достаточно велико, чтобы оправдать сосредоточение на этом за счет других функций? Действительно ли есть огромное преимущество в добавлении функций основного языка, которые уже (в основном) могут быть сделаны через библиотеки и препроцессоры, такие как QT? Возможно, но необходимость гораздо менее актуальна, чем если бы таких библиотек не было. Хотя для ваших конкретных предложений, я считаю, что запрет на использование шаблонов сделает его совершенно бесполезным. Например, вы не сможете использовать отражение в стандартной библиотеке. Какое отражение не будетstd::vector? Шаблоны являются огромной частью C ++. Функция, которая не работает с шаблонами, в основном бесполезна.

Но вы правы, некоторая форма отражения может быть реализована. Но это было бы серьезным изменением в языке. Как и сейчас, типы являются исключительно конструкцией времени компиляции. Они существуют для пользы компилятора и ничего больше. После того , как код был скомпилирован, там нет никаких классов. Если вы растягиваете себя, вы можете утверждать, что функции все еще существуют, но на самом деле все, что есть, - это набор инструкций для ассемблера прыжков и множество push / pop стеков. При добавлении таких метаданных не так много всего.

Но, как я уже сказал, есть предложение об изменениях в модели компиляции, добавлении автономных модулей, хранении метаданных для выбранных типов, что позволяет другим модулям ссылаться на них без необходимости связываться с #includes. Это хорошее начало, и, честно говоря, я удивлен, что стандартный комитет не просто выбросил предложение о том, что оно слишком велико. Так, может быть, через 5-10 лет? :)


2
Разве большинство этих проблем уже не должно быть решено с помощью символов отладки? Не то чтобы это было бы быстродействующим (из-за упомянутых вами вложений и оптимизации), но вы могли бы допустить возможность отражения, выполняя любые символы отладки.
cledary

2
Еще одна вещь о вашем первом замечании: насколько я знаю, никто не пытался добавить отражение в реализацию C ++. Там нет хорошего опыта с этим. Комитет, вероятно, неохотно возьмет на себя инициативу, особенно после exportи vector<bool>.
Дэвид Торнли

18
Я согласен, что C ++ не должен иметь отражения во время выполнения. Но у отражения времени компиляции есть немного из вышеупомянутых проблем, и он мог бы использоваться для того, чтобы кто-то мог построить отражение времени выполнения на определенных классах, если они захотят. Возможность доступа к типу, имени и функциям n-го метода и n-го родителя класса через шаблон? И получить число таких во время компиляции? Можно было бы сделать автоматическое отражение на основе CRTP, пока никто не платит за то, что они не используют.
Якк - Адам Невраумонт

15
Ваш третий пункт во многих отношениях является наиболее важным: C ++ предназначен для написания автономного кода на платформах, где память стоит денег; если удаление некоторого неиспользуемого кода позволит программе уместиться в микроконтроллере стоимостью 2,00 долл. США, а не в 2,50 долл. США, а в случае использования кода в 1 000 000 единиц, устранение этого кода может сэкономить 500 000 долл. США. Без размышлений статический анализ часто может выявить более 90% недоступного кода; если Reflection разрешен, то все, что может быть достигнуто с помощью Reflection, должно считаться достижимым, даже если 90% этого не допускается.
Суперкат

2
есть определенно что - то , что может быть улучшена легко с помощью comitee, это, наконец , сказать черным по белому написано, что typeinfo«s name()функция должна возвращать имя , которое было набранный программистом , а не что - то неопределенным. И дайте нам строковый преобразователь для счетчиков. Это действительно важно для сериализации / десериализации, создания заводов и т. Д.
v.oddou

38

Отражение требует хранения метаданных о типах, которые можно запрашивать. Поскольку C ++ компилируется в собственный машинный код и претерпевает значительные изменения в связи с оптимизацией, представление высокого уровня приложения в значительной степени теряется в процессе компиляции, следовательно, запросить их во время выполнения будет невозможно. Java и .NET используют представление очень высокого уровня в двоичном коде для виртуальных машин, что делает возможным этот уровень отражения. Однако в некоторых реализациях C ++ есть нечто, называемое информацией о типе времени выполнения (RTTI), которое можно рассматривать как упрощенную версию отражения.


15
RTTI в стандарте C ++.
Даниэль Уорвикер

1
Но не все реализации C ++ являются стандартными. Я видел реализации, которые не поддерживают RTTI.
Мехрдад Афшари

3
И большинство реализаций, которые поддерживают RTTI, также поддерживают его отключение с помощью параметров компилятора.
Майкл Кон

21

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

C ++, по сути, очень, очень сложный макро ассемблер. Это НЕ (в традиционном смысле) язык высокого уровня, такой как C #, Java, Objective-C, Smalltalk и т. Д.

Хорошо иметь разные инструменты для разных работ. Если у нас есть только молотки, все будет выглядеть как гвозди и т. Д. Наличие языков сценариев полезно для некоторых заданий, а отражающие ОО-языки (Java, Obj-C, C #) полезны для другого класса заданий и супер эффективные базовые языки, близкие к машине, полезны для еще одного класса заданий (C ++, C, Assembler).

C ++ делает потрясающую работу по расширению технологии Assembler до невероятных уровней управления сложностью и абстракций, чтобы сделать программирование более широким, более сложными задачами, намного более доступными для людей. Но это не обязательно тот язык, который лучше всего подходит для тех, кто подходит к своей проблеме с точки зрения высокого уровня (Lisp, Smalltalk, Java, C #). Если вам нужен язык с этими функциями, чтобы наилучшим образом реализовать решение ваших проблем, то поблагодарите тех, кто создал такие языки, для всех нас!

Но C ++ предназначен для тех, кто по каким-либо причинам должен иметь сильную корреляцию между своим кодом и работой базовой машины. Будь то эффективность, программирование драйверов устройств, взаимодействие с низкоуровневыми службами ОС или что-то еще, C ++ лучше подходит для этих задач.

C #, Java, Objective-C все требуют гораздо большей, более богатой системы времени выполнения для поддержки их выполнения. Это время выполнения должно быть доставлено в соответствующую систему - предварительно установлено для поддержки работы вашего программного обеспечения. И этот уровень необходимо поддерживать для различных целевых систем, настроенных НЕКОТОРЫМ ДРУГИМ ЯЗЫКОМ, чтобы он работал на этой платформе. И этот средний уровень - этот адаптивный уровень между операционной системой хоста и вашим кодом - среда выполнения, почти всегда пишется на языке, таком как C или C ++, где эффективность равна # 1, где предсказуемое понимание точного взаимодействия между программным и аппаратным обеспечением может быть хорошим понял и манипулировал с максимальной прибылью.

Я люблю Smalltalk, Objective-C, и имею богатую систему времени выполнения с отражением, метаданными, сборкой мусора и т. Д. Для использования этих возможностей можно написать удивительный код! Но это просто более высокий уровень в стеке, уровень, который должен опираться на более низкие уровни, которые сами должны в конечном итоге находиться на ОС и оборудовании. И нам всегда будет нужен язык, который лучше всего подходит для построения этого уровня: C ++ / C / Assembler.

Приложение: C ++ 11/14 продолжают расширять возможности C ++ для поддержки абстракций и систем более высокого уровня. Потоки, синхронизация, точные модели памяти, более точные определения абстрактных машин позволяют разработчикам C ++ достигать многих абстракций высокого уровня, которые некоторые из этих высокоуровневых языков использовали для монопольного домена, продолжая при этом обеспечивать близкий к производительность металла и отличная предсказуемость (т.е. минимальные подсистемы времени выполнения). Возможно, средства отражения будут выборочно включены в будущей редакции C ++ для тех, кто этого хочет - или, возможно, библиотека будет предоставлять такие сервисы времени выполнения (может быть, есть один сейчас или его начало в ускорении?).


Ваша точка зрения о времени выполнения языка, который должен быть скомпилирован на другом языке, неверна в случае Objective-C, так как его время выполнения написано на C (Objective-C является надмножеством).
Ричард Дж. Росс III

Это различие без разницы. Какая разница, когда, в конце концов, подсистема времени выполнения, которую использует Objective-C, фактически написана не в Objective-C, а скорее в C?
Мордачай

3
Мне жаль; но пока вы правильно связываете его, вы можете скомпилировать программу Objective-C на C, фактически я сделал это здесь: stackoverflow.com/a/10290255/427309 . Все вышеприведенное утверждение неверно. Среда выполнения полностью доступна через C, и это одна из вещей, которая делает его таким мощным динамическим языком.
Ричард Дж. Росс III

1
Среда выполнения C - это просто динамическая библиотека, содержащая код для стандартной библиотеки C. То же самое для "C ++ runtime". Это сильно отличается от системы времени выполнения, такой как Objective-C. Кроме того ... хотя я полагаю, что вы могли бы технически использовать среду выполнения Objective C в C, это все еще всего лишь программа C, которая использует среду выполнения Objective C - вы не можете скомпилировать реальную программу Objective C в C.
celticminstrel

2
C ++ 11 с моделью памяти + атомика делает его более похожим на портативный ассемблер. Это не высокоуровневые вещи, это низкоуровневые вещи, для которых C ++ ранее не обладал портативной поддержкой. Но количество UB в C ++, если вы делаете что-то не так, делает его очень непохожим на языки на основе VM, такие как Java, а также на любой конкретный ассемблер. Например, в исходном коде C ++ переполнение со знаком является полностью UB, и компилятор может оптимизировать на основе этого факта, даже если компиляция, скажем, для x86, но в asm почти на всех платформах это просто оборачивается. Современный C ++ очень далек от переносимого языка ассемблера.
Питер Кордес

11

Если вы действительно хотите понять конструктивные решения, связанные с C ++, найдите копию The Annotated C ++ Reference Manual от Эллиса и Страуструпа. Он НЕ соответствует последнему стандарту, но он проходит через оригинальный стандарт и объясняет, как все работает и как часто, как они так поступили.


6
Также дизайн и развитие C ++ по Страуструпу
Джеймс Хопкин

9

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

Компилятор C ++ ничего не держит (ну, игнорируя RTTI), поэтому вы не получите отражения в языке. (Компиляторы Java и C # хранят только классы, имена методов и возвращаемые типы, поэтому вы получаете немного данных об отражении, но не можете проверить выражения или структуру программы, а это означает, что даже в этих языках с «отражением» информация, которую вы можете получить, довольно скудна, и, следовательно, вы действительно не можете много анализировать).

Но вы можете выйти за пределы языка и получить полный потенциал отражения. Ответ на другое обсуждение переполнения стека при отражении в C обсуждает это.


7

Отражение может быть и было реализовано в C ++ раньше.

Это не нативная функция c ++, потому что она требует больших затрат (память и скорость), которые не должны устанавливаться языком по умолчанию - язык ориентирован на «максимальную производительность по умолчанию».

Поскольку вы не должны платить за то, что вам не нужно, и, как вы сами говорите, в редакторах нужно больше, чем в других приложениях, то это должно быть реализовано только там, где вам это нужно, а не «принудительно» для всего кода ( вам не нужно размышлять обо всех данных, с которыми вы будете работать в редакторе или другом подобном приложении).


3
и вы не отправляете символы, потому что это позволит вашим клиентам / конкурентам взглянуть на ваш код ... это часто считается плохой вещью.
gbjbaanb

Вы правы, я даже не
думал

6

Причина, по которой C ++ не имеет отражения, состоит в том, что для этого потребуется, чтобы компиляторы добавляли символьную информацию в объектные файлы, например, какие члены имеют тип класса, информацию о членах, о функциях и обо всем. По сути, это сделает бесполезными включаемые файлы, так как информация, отправленная объявлениями, будет затем считываться из этих объектных файлов (затем модулей). В C ++ определение типа может встречаться в программе несколько раз путем включения соответствующих заголовков (при условии, что все эти определения одинаковы), поэтому необходимо будет решить, куда поместить информацию об этом типе, так же, как назвать ее осложнение здесь. Еще одна сильная сторона - агрессивная оптимизация, выполняемая компилятором C ++, который может оптимизировать десятки экземпляров шаблонов классов. Это возможно, но поскольку C ++ совместим с C,


1
Я не понимаю, как агрессивная оптимизация компилятора является сильной стороной. Можете ли вы уточнить? Если компоновщик может удалить дубликаты определений встроенных функций, в чем проблема с дублирующейся информацией об отражении? Разве символьная информация не добавляется в объектные файлы для отладчиков?
Роб Кеннеди

1
Проблема в том, что ваша информация об отражении может быть недействительной. Если компилятор исключает 80% определений вашего класса, что скажут ваши метаданные отражения? В C # и Java язык гарантирует, что если вы определите класс, он останется определенным. C ++ позволяет компилятору оптимизировать его.
Джалф

1
@Rob, оптимизации - это еще один момент, не связанный с усложнением нескольких классов. Смотрите комментарий @ jalf (и его ответ), что я имел ввиду.
Йоханнес Шауб -

4
Если я создаю экземпляр отражения <T>, то не выбрасываю никакую информацию Т. Это не кажется неразрешимой проблемой.
Джозеф Гарвин

3

Существует множество случаев использования рефлексии в C ++, которые не могут быть адекватно решены с помощью конструкций времени компиляции, таких как метапрограммирование шаблона.

N3340 предлагает богатые указатели как способ отражения в C ++. Среди прочего, он решает проблему не оплаты функции, если вы ее не используете.


2

По словам Алистера Кокберна, подтип не может быть гарантирован в отражающей среде .

Отражение больше относится к системам скрытой типизации. В C ++ вы знаете, какой у вас тип, и знаете, что с ним можно сделать.


В более общем смысле, возможность проверять наличие функции, которая не существует, без введения неопределенного поведения, делает возможным, что добавление этой функции в более позднюю версию класса изменит четко определенное поведение уже существующих программ и будет следовательно, невозможно гарантировать, что добавление этой функции не «сломает» что-то.
Суперкат

2

Отражение может быть необязательным, как директива препроцессора. Что-то вроде

#pragma enable reflection

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


2

Если бы C ++ мог иметь:

  • данные членов класса для имен переменных, типов переменных и const модификатора
  • итератор аргументов функции (только позиция вместо имени)
  • данные членов класса для имен функций, типа возвращаемого значения и const модификатора
  • список родительских классов (в том же порядке, как определено)
  • данные для членов шаблона и родительских классов; расширенный шаблон (то есть фактический тип будет доступен для API отражения, а не «информация шаблона о том, как туда попасть»)

Этого было бы достаточно для создания очень простых в использовании библиотек суть обработки типов данных, которая так распространена в современных веб-приложениях и приложениях баз данных (все формы, механизмы обмена сообщениями, парсеры xml / json, сериализация данных и т. Д.).

Например, основная информация, поддерживаемая Q_PROPERTYмакросом (часть Qt Framework), http://qt.nokia.com/doc/4.5/properties.html, расширенная для охвата методов класса и e), будет чрезвычайно полезна для C ++ и для Сообщество программного обеспечения в целом.

Конечно, рефлексия, на которую я ссылаюсь, не будет охватывать семантического значения или более сложных вопросов (таких как номера строк исходного кода комментариев, анализ потока данных и т. Д.), Но я также не думаю, что они необходимы, чтобы быть частью языкового стандарта.


@Vlad: Да, если кто-то добавляет функции, поддерживающие отражение в языке, вы получаете отражение в языке. Это может произойти только в том случае, если языковой комитет примет такое решение, и я думаю, что этого не произойдет с 2011 года, и я сомневаюсь, что до 2020 года будет еще один стандарт C ++. Итак, хорошая мысль. В то же время, если вы хотите добиться прогресса, вам, вероятно, придется выйти за пределы C ++.
Ира Бакстер


0

Отражение в C ++, я считаю, крайне важно, если C ++ будет использоваться в качестве языка для доступа к базе данных, обработки веб-сеансов / http и разработки GUI. Отсутствие отражения не позволяет ORM (таким как Hibernate или LINQ), синтаксическим анализаторам XML и JSON создавать экземпляры классов, сериализацию данных и многие другие значения (когда для создания экземпляра класса необходимо использовать изначально не типированные данные).

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

Мне разработчик прошивки не нуждается в отражении для чтения данных с последовательного порта - тогда нормально не использовать коммутатор. Но как разработчик базы данных, который хочет продолжать использовать C ++, я постоянно сталкиваюсь с ужасным, сложным в обслуживании кодом, который отображает данные между членами данных и конструкциями базы данных.

Ни Boost-сериализация, ни другой механизм на самом деле не решают отражения - это должно быть сделано компилятором - и как только это будет сделано, C ++ снова будет изучен в школах и использован в программном обеспечении, которое имеет дело с обработкой данных.

Для меня это проблема № 1 (а примитивы с наивным потоком - проблема № 2).


4
Кто сказал , C ++ является для использования в качестве языка для БД Access, веб - сессии hnadling или графического интерфейса разработчика? Есть много гораздо лучших языков для такого рода вещей. И переключатель времени компиляции не решит проблему. Обычно решение о включении или отключении отражения принимается не для каждого файла. Он может работать, если он может быть включен на отдельных типах. Если программист может указать с атрибутом или подобным при определении типа, должны ли генерироваться метаданные отражения для него. Но глобальный переключатель? Вы бы наносили вред 90% языка, чтобы сделать его на 10% проще.
jalf

Тогда, если мне нужна программа, которая кроссплатформенная и имеет доступ к графическому интерфейсу, что мне следует использовать? Негибкий свинг Java? На окнах только C #? Но нужно сказать правду, и правда в том, что есть много программ, которые скомпилированы в исполняемый код и предлагают графический интерфейс и доступ к базам данных, поэтому они должны использовать некоторую базу данных и поддержку графического интерфейса ... И они не ' т с использованием QT. (он должен был называться MT (набор инструментов для монстров))
Coyote21

1
@ Coyote21: C # не был только для Windows в течение многих лет. (Хотя я не фанат Mono, он работает достаточно хорошо для большинства вещей.) И Swing - не единственный инструментарий GUI для Java. По правде говоря, любой из них будет лучшим выбором, если вы хотите кроссплатформенность. C ++ почти всегда будет содержать специфичные для платформы части здесь или там, если вы делаете что-то нетривиальное.
cHao

Нет никаких причин, почему вам нужно отражение для ORM. Вы можете достичь всего этого с помощью шаблонов. Здесь есть множество фреймворков, которые предоставляют ORM для C ++.
MrFox

0

Это в основном потому, что это «необязательный дополнительный». Многие люди предпочитают C ++ языкам, таким как Java и C #, чтобы они могли лучше контролировать вывод компилятора, например, небольшую и / или более быструю программу.

Если вы решите добавить отражение, существуют различные решения .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.