Por que o C ++ não tem reflexão?


337

Esta é uma pergunta um tanto bizarra. Meus objetivos são entender a decisão de design da linguagem e identificar as possibilidades de reflexão em C ++.

  1. Por que o comitê de linguagem C ++ não foi para a implementação da reflexão na linguagem? A reflexão é muito difícil em um idioma que não é executado em uma máquina virtual (como java)?

  2. Se alguém implementasse a reflexão para C ++, quais serão os desafios?

Acho que os usos da reflexão são bem conhecidos: os editores podem ser escritos com mais facilidade, o código do programa será menor, as zombarias podem ser geradas para testes de unidade e assim por diante. Mas seria ótimo se você pudesse comentar sobre os usos da reflexão também.

Respostas:


631

Existem vários problemas com a reflexão em C ++.

  • É muito trabalhoso acrescentar, e o comitê de C ++ é bastante conservador e não gasta tempo com novos recursos radicais, a menos que tenham certeza de que valerá a pena. (Uma sugestão para adicionar um sistema de módulos semelhante aos assemblies .NET foi feita e, embora eu ache que há um consenso geral de que seria bom ter, não é a principal prioridade no momento e foi adiada até bem depois C ++ 0x. A motivação para esse recurso é se livrar do #includesistema, mas também permitiria pelo menos alguns metadados).

  • Você não paga pelo que não usa. Essa é uma das filosofias básicas de design básicas subjacentes ao C ++. Por que meu código carrega metadados se talvez nunca precise dele? Além disso, a adição de metadados pode inibir a otimização do compilador. Por que devo pagar esse custo no meu código se talvez nunca precise desses metadados?

  • O que nos leva a outro grande ponto: o C ++ oferece muito poucas garantias sobre o código compilado. É permitido ao compilador fazer praticamente o que quiser, desde que a funcionalidade resultante seja o que é esperado. Por exemplo, suas aulas não precisam estar lá . O compilador pode otimizá-los, incorporar tudo o que eles fazem, e frequentemente faz exatamente isso, porque mesmo o código de modelo simples tende a criar algumas instanciações de modelo. A biblioteca padrão C ++ conta com essa otimização agressiva. Os atuadores só têm desempenho se a sobrecarga de instanciar e destruir o objeto puder ser otimizada. operator[]em um vetor é apenas comparável à indexação de matriz bruta no desempenho, porque todo o operador pode ser incorporado e, portanto, removido inteiramente do código compilado. C # e Java oferecem muitas garantias sobre a saída do compilador. Se eu definir uma classe em C #, essa classe existirá no assembly resultante. Mesmo que eu nunca o use. Mesmo que todas as chamadas para suas funções de membro possam ser incorporadas. A classe tem que estar lá, para que a reflexão possa encontrá-la. Parte disso é aliviada pela compilação de C # no bytecode, o que significa que o compilador JIT poderemova definições de classe e funções embutidas, se desejar, mesmo que o compilador C # inicial não possa. No C ++, você tem apenas um compilador e ele precisa gerar código eficiente. Se você tivesse permissão para inspecionar os metadados de um executável C ++, esperaria ver todas as classes definidas, o que significa que o compilador teria que preservar todas as classes definidas, mesmo que não sejam necessárias.

  • E depois existem modelos. Modelos em C ++ não são nada como genéricos em outros idiomas. Toda instanciação de modelo cria um novo tipo. std::vector<int>é uma classe completamente separada de std::vector<float>. Isso adiciona muitos tipos diferentes em um programa inteiro. O que nossa reflexão deveria ver? O modelo std::vector ? Mas como pode, já que é uma construção de código-fonte, que não tem significado no tempo de execução? Teria que ver as classes separadas std::vector<int>e std::vector<float>. E std::vector<int>::iteratore std::vector<float>::iterator, o mesmo paraconst_iteratore assim por diante. E depois que você entra na metaprogramação de modelos, você acaba instanciando centenas de modelos, todos os quais são incorporados e removidos novamente pelo compilador. Eles não têm significado, exceto como parte de um metaprograma em tempo de compilação. Todas essas centenas de classes devem ser visíveis à reflexão? Eles precisariam, porque, caso contrário, nossa reflexão seria inútil, se nem sequer garantir que as classes que eu defini realmente estarão lá . E um problema secundário é que a classe de modelo não existe até que seja instanciada. Imagine um programa que use std::vector<int>. Nosso sistema de reflexão deveria ser capaz de ver std::vector<int>::iterator? Por um lado, você certamente esperaria isso. É uma classe importante, e é definida em termos de std::vector<int>, o que fazexiste nos metadados. Por outro lado, se o programa nunca realmente usar esse modelo de classe de iterador, seu tipo nunca será instanciado e, portanto, o compilador não terá gerado a classe em primeiro lugar. E é tarde demais para criá-lo em tempo de execução, pois requer acesso ao código-fonte.

  • E, finalmente, a reflexão não é tão vital em C ++ quanto em C #. O motivo é novamente a metaprogramação de modelos. Ele não pode resolver tudo, mas em muitos casos em que você recorreria à reflexão, é possível escrever um metaprograma que faça a mesma coisa em tempo de compilação. boost::type_traitsé um exemplo simples. Você quer saber sobre o tipo T? Verifique o seu type_traits. Em C #, você teria que pescar após seu tipo usando reflexão. A reflexão ainda seria útil para algumas coisas (o principal uso que eu posso ver, que a metaprogramação não pode substituir facilmente, é para código de serialização gerado automaticamente), mas carregaria alguns custos significativos para o C ++, e isso não é necessário sempre que necessário. está em outros idiomas.

Edit: Em resposta aos comentários:

cdleary: Sim, os símbolos de depuração fazem algo semelhante, pois armazenam metadados sobre os tipos usados ​​no executável. Mas eles também sofrem com os problemas que descrevi. Se você já tentou depurar uma versão, saberá o que quero dizer. Existem grandes lacunas lógicas nas quais você criou uma classe no código-fonte, que foi embutida no código final. Se você usasse a reflexão para qualquer coisa útil, seria necessário que ela fosse mais confiável e consistente. Assim, os tipos desapareciam e desapareciam quase toda vez que você compila. Você altera um pequeno detalhe, e o compilador decide alterar quais tipos são incorporados e quais não, como resposta. Como você extrai algo útil disso quando você ' nem sequer garantimos que os tipos mais relevantes serão representados nos seus metadados? O tipo que você estava procurando pode ter existido na última compilação, mas agora se foi. E amanhã, alguém verificará uma pequena mudança inocente em uma pequena função inocente, o que tornará o tipo suficientemente grande para que não fique completamente embutido, para que volte sempre. Isso ainda é útil para símbolos de depuração, mas não muito mais do que isso. Eu odiaria tentar gerar código de serialização para uma classe sob esses termos. mas não muito mais que isso. Eu odiaria tentar gerar código de serialização para uma classe sob esses termos. mas não muito mais que isso. Eu odiaria tentar gerar código de serialização para uma classe sob esses termos.

Evan Teran: É claro que esses problemas poderiam ser resolvidos. Mas isso remonta ao meu ponto 1. Daria muito trabalho, e o comitê C ++ tem muitas coisas que consideram mais importantes. O benefício de obter uma reflexão limitada (e seria limitada) em C ++ é realmente grande o suficiente para justificar o foco nisso à custa de outros recursos? Existe realmente um grande benefício em adicionar recursos à linguagem principal que já pode (principalmente) ser feita através de bibliotecas e pré-processadores como os QTs? Talvez, mas a necessidade é muito menos urgente do que se essas bibliotecas não existissem. Porém, para as suas sugestões específicas, acredito que a proibição de modelos tornaria completamente inútil. Você não conseguiria usar a reflexão na biblioteca padrão, por exemplo. Que tipo de reflexão não seriastd::vector? Os modelos são uma grande parte do C ++. Um recurso que não funciona em modelos é basicamente inútil.

Mas você está certo, alguma forma de reflexão pode ser implementada. Mas seria uma grande mudança no idioma. Como é agora, os tipos são exclusivamente uma construção em tempo de compilação. Eles existem para o benefício do compilador e nada mais. Uma vez que o código foi compilado, não estão sem aulas. Se você se esforçar, poderá argumentar que as funções ainda existem, mas, na verdade, tudo o que há são várias instruções do assembler de salto e muitos push / pop da pilha. Não há muito o que fazer ao adicionar esses metadados.

Mas, como eu disse, há uma proposta de alterações no modelo de compilação, adicionando módulos independentes, armazenando metadados para tipos selecionados, permitindo que outros módulos os referenciem sem ter que mexer com #includes. É um bom começo e, para ser sincero, estou surpreso que o comitê padrão não tenha lançado a proposta apenas por ser uma mudança muito grande. Então, talvez em 5 a 10 anos? :)


2
A maioria desses problemas já não precisa ser resolvida por símbolos de depuração? Não que ele tenha desempenho (por causa do inlining e otimização que você mencionou), mas você pode permitir a possibilidade de reflexão fazendo o que os símbolos de depuração fazem.
Cdcely

2
Outra coisa sobre o seu primeiro ponto: até onde eu sei, ninguém tentou adicionar reflexão a uma implementação em C ++. Não há uma boa experiência com isso. O Comitê provavelmente relutará em assumir a liderança, especialmente depois exporte vector<bool>.
22630 David Thornley

18
Concordo que o C ++ não deve ter reflexão de tempo de execução. Porém, a reflexão em tempo de compilação tem alguns dos problemas acima e pode ser usada para alguém criar uma reflexão em tempo de execução em classes específicas, se assim o desejar. Ser capaz de acessar o tipo, o nome e os recursos do enésimo método e enésimo pai de uma classe por meio de um modelo? E obter o número de tais em tempo de compilação? Tornaria factível a reflexão automática baseada em CRTP, enquanto ninguém está pagando pelo que não está usando.
Yakk - Adam Nevraumont 12/12

15
Seu terceiro ponto é, em muitos aspectos, o mais importante: o C ++ deve ser adequado para escrever código independente em plataformas onde a memória custa dinheiro; se a eliminação de algum código não utilizado permitiria que um programa cabesse em um microcontrolador que custa US $ 2,00, em vez de um que custa US $ 2,50, e se o código estiver em 1.000.000 unidades, a eliminação desse código pode economizar US $ 500.000. Sem reflexão, a análise estática geralmente pode identificar mais de 90% do código inacessível; se o Reflection for permitido, qualquer coisa que possa ser alcançada através do Reflection deve ser presumível alcançável, mesmo que 90% dele não seja.
Supercat 4/13

2
não é definitivamente algo que pode ser melhorado facilmente pela comitee, é para finalmente dizer preto no branco que typeinfo's name()função deve retornar o nome que foi digitado pelo programador e não algo indefinido. E nos dê um stringifier para enumeradores também. Esta é realmente crucial para serialização / desserialização, ajudando na tomada de fábricas etc.
v.oddou

38

A reflexão requer que alguns metadados sobre os tipos sejam armazenados em algum lugar que possa ser consultado. Como o C ++ é compilado no código de máquina nativo e sofre grandes alterações devido à otimização, a visualização de alto nível do aplicativo é praticamente perdida no processo de compilação; consequentemente, não será possível consultá-los em tempo de execução. Java e .NET usam uma representação de nível muito alto no código binário para máquinas virtuais, tornando possível esse nível de reflexão. Em algumas implementações de C ++, no entanto, existe algo chamado RTTI (Run Time Type Information) que pode ser considerado uma versão simplificada da reflexão.


15
RTTI está no padrão C ++.
Daniel Earwicker

11
Mas nem todas as implementações de C ++ são padrão. Eu já vi implementações que não suportam RTTI.
Mehrdad Afshari

3
E a maioria das implementações que suportam RTTI também suportam desativá-lo por meio de opções do compilador.
22630 Michael Kohne

21

Todos os idiomas não devem tentar incorporar todos os recursos de qualquer outro idioma.

C ++ é essencialmente um montador de macros muito, muito sofisticado. NÃO é (no sentido tradicional) uma linguagem de alto nível como C #, Java, Objective-C, Smalltalk, etc.

É bom ter ferramentas diferentes para trabalhos diferentes. Se tivermos apenas martelos, tudo parecerá prego, etc. Ter linguagens de script é útil para alguns trabalhos, e linguagens OO reflexivas (Java, Obj-C, C #) são úteis para outra classe de trabalhos, e super linguagens básicas simples e próximas da máquina são úteis para mais uma classe de tarefas (C ++, C, Assembler).

O C ++ faz um trabalho incrível de estender a tecnologia Assembler para níveis incríveis de gerenciamento de complexidade e abstrações para tornar a programação tarefas maiores e mais complexas muito mais possíveis para os seres humanos. Mas não é necessariamente uma linguagem mais adequada para aqueles que estão abordando o problema de uma perspectiva estritamente de alto nível (Lisp, Smalltalk, Java, C #). Se você precisar de um idioma com esses recursos para implementar melhor uma solução para seus problemas, agradeça àqueles que criaram esses idiomas para que todos nós possamos usar!

Mas C ++ é para aqueles que, por qualquer motivo, precisam ter uma forte correlação entre seu código e a operação da máquina subjacente. Seja sua eficiência, drivers de dispositivo de programação ou interação com os serviços de SO de nível inferior ou qualquer outra coisa, o C ++ é mais adequado para essas tarefas.

C #, Java, Objective-C exigem um sistema de tempo de execução muito maior e mais rico para suportar sua execução. Esse tempo de execução deve ser entregue ao sistema em questão - pré-instalado para suportar a operação do seu software. E essa camada deve ser mantida para vários sistemas de destino, personalizados por ALGUM OUTRO IDIOMA para fazê-lo funcionar nessa plataforma. E essa camada intermediária - aquela camada adaptativa entre o sistema operacional host e o seu código - o tempo de execução, é quase sempre escrita em uma linguagem como C ou C ++, onde a eficiência é a número 1, na qual é possível entender previsivelmente a interação exata entre software e hardware. entendido e manipulado para obter o ganho máximo.

Eu amo Smalltalk, Objective-C, e ter um sistema de tempo de execução rico com reflexão, metadados, coleta de lixo, etc. É possível escrever um código incrível para aproveitar essas facilidades! Mas isso é simplesmente uma camada mais alta na pilha, uma camada que deve repousar nas camadas inferiores, e que, por fim, elas devem estar no SO e no hardware. E sempre precisaremos de uma linguagem mais adequada para criar essa camada: C ++ / C / Assembler.

Adendo: o C ++ 11/14 continua expandindo a capacidade do C ++ para oferecer suporte a abstrações e sistemas de nível superior. Threading, sincronização, modelos de memória precisos, definições de máquina abstrata mais precisas estão permitindo que os desenvolvedores de C ++ obtenham muitas das abstrações de alto nível que algumas dessas linguagens de alto nível costumavam ter domínio exclusivo, enquanto continuam fornecendo informações próximas a desempenho metálico e excelente previsibilidade (ou seja, subsistemas de tempo de execução mínimo). Talvez os recursos de reflexão sejam seletivamente ativados em uma revisão futura do C ++, para aqueles que o desejam - ou talvez uma biblioteca forneça esses serviços de tempo de execução (talvez exista um agora ou o início de um impulso).


Seu argumento sobre o tempo de execução de uma linguagem que precisa ser compilado em outra linguagem não é verdadeiro no caso do Objective-C, pois o tempo de execução é escrito em C (do qual o Objective-C é um superconjunto).
Richard J. Ross III

Essa é uma distinção sem diferença. Que diferença faz, quando no final, o subsistema de tempo de execução que o Objective-C usa, na verdade, não está escrito em Objective-C, mas em C?
Mordachai

3
Eu sinto Muito; mas contanto que você o vincule corretamente, você pode compilar um programa de objetivo-c em C, na verdade eu o fiz aqui: stackoverflow.com/a/10290255/427309 . Toda a sua declaração acima é falsa. O tempo de execução é totalmente acessível através do C, e é uma das coisas que o torna uma linguagem dinâmica tão poderosa.
Richard J. Ross III

11
O "tempo de execução C" é apenas uma biblioteca dinâmica que contém o código da biblioteca padrão C. O mesmo para o "tempo de execução C ++". É bem diferente de um sistema de tempo de execução como o do Objective-C. Além disso ... embora eu suponha que você possa tecnicamente usar o tempo de execução do Objective-C em C, ainda é apenas um programa C que usa o tempo de execução do Objective-C - você não pode compilar um programa de Objective-C real em C.
celticminstrel

2
O C ++ 11, com um modelo de memória + atomics, torna-o mais como um montador portátil. Essas não são coisas de alto nível, são coisas de baixo nível para as quais o C ++ anteriormente não tinha suporte portátil. Mas a quantidade de UB em C ++, se você fizer algo errado, torna muito diferente de linguagens baseadas em VM, como Java, e também de qualquer linguagem assembly específica. por exemplo, o overflow de assinaturas é totalmente UB na fonte C ++ e o compilador pode otimizar com base nesse fato, mesmo que a compilação digamos x86, mas no asm em quase todas as plataformas, ela apenas será aplicada. O C ++ moderno está muito longe de uma linguagem assembly portátil.
Peter Cordes

11

Se você realmente deseja entender as decisões de design que envolvem o C ++, encontre uma cópia do Manual de Referência do C ++ anotado por Ellis e Stroustrup. NÃO está atualizado com o padrão mais recente, mas passa pelo padrão original e explica como as coisas funcionam e, com frequência, como elas foram assim.


6
Também Design e Evolução do C ++ por Stroustrup
James Hopkin

9

A reflexão para as linguagens contidas é sobre quanto do código-fonte o compilador está disposto a deixar no código do objeto para permitir a reflexão e quanto mecanismo de análise está disponível para interpretar essas informações refletidas. A menos que o compilador mantenha todo o código-fonte por perto, a reflexão será limitada em sua capacidade de analisar os fatos disponíveis sobre o código-fonte.

Compilador do C ++ não mantém qualquer coisa ao redor (bem, ignorando RTTI), para que não fique reflexão na língua. (Os compiladores Java e C # mantêm apenas classes, nomes de métodos e tipos de retorno, para que você obtenha um pouco de dados de reflexão, mas não pode inspecionar expressões ou estrutura de programa, o que significa que mesmo nessas linguagens "ativadas para reflexão" as informações que você pode obter são muito escassas e, conseqüentemente, você realmente não pode fazer muita análise).

Mas você pode sair do idioma e obter recursos completos de reflexão. A resposta para outra discussão excedente de pilha na reflexão em C discute isso.


7

A reflexão pode ser e foi implementada em c ++ anteriormente.

Não é um recurso nativo do c ++ porque possui um alto custo (memória e velocidade) que não deve ser definido por padrão pelo idioma - o idioma é orientado para "desempenho máximo por padrão".

Como você não deve pagar pelo que não precisa e, como você mesmo diz, é mais necessário nos editores do que em outros aplicativos, ele deve ser implementado apenas onde você precisar, e não "forçado" a todo o código ( você não precisa refletir sobre todos os dados com os quais trabalhará em um editor ou outro aplicativo similar).


3
e você não envia símbolos, pois isso permitiria que seus clientes / concorrentes analisassem seu código ... isso costuma ser considerado uma coisa ruim.
gbjbaanb 11/12/08

Você está certo, eu não mesmo que sobre o problema exposição código :)
Klaim

6

O motivo pelo qual o C ++ não reflete é que isso exigiria que os compiladores adicionassem informações de símbolos aos arquivos de objetos, como os membros de um tipo de classe, informações sobre os membros, sobre as funções e tudo mais. Isso essencialmente tornaria inúteis os arquivos de inclusão, pois as informações enviadas pelas declarações seriam lidas a partir desses arquivos de objeto (módulos então). No C ++, uma definição de tipo pode ocorrer várias vezes em um programa, incluindo os respectivos cabeçalhos (desde que todas essas definições sejam iguais); portanto, é necessário decidir onde colocar as informações sobre esse tipo, assim como nomear um complicação aqui. A otimização agressiva feita por um compilador C ++, que pode otimizar dezenas de instanciações de modelos de classe, é outro ponto forte. É possível, mas como o C ++ é compatível com o C,


11
Não entendo como a otimização agressiva do compilador é um ponto forte. Você pode elaborar? Se o vinculador puder remover definições duplicadas de funções em linha, qual é o problema com informações duplicadas de reflexão? As informações de símbolos não são adicionadas aos arquivos de objeto de qualquer maneira, para depuradores?
Rob Kennedy

11
O problema é que suas informações de reflexão podem ser inválidas. Se o compilador eliminar 80% de suas definições de classe, o que seus metadados de reflexão dirão? Em C # e Java, a linguagem garante que, se você definir uma classe, ela permanecerá definida. O C ++ permite que o compilador o otimize.
jalf

11
@ Rob, as otimizações são outro ponto, não ligado à complicação de várias classes. Veja o comentário de @ jalf (e sua resposta) para o que eu quis dizer.
Johannes Schaub - litb 31/08/09

4
Se eu instanciar refletir <T>, não jogue fora nenhuma informação de T. Isso não parece ser um problema insolúvel.
31711 Joseph Garvin

3

Existem muitos casos de uso da reflexão em C ++ que não podem ser tratados adequadamente usando construções de tempo de compilação, como a metaprogramação de modelos.

O N3340 propõe indicadores avançados como uma maneira de introduzir reflexão em C ++. Entre outras coisas, trata da questão de não pagar por um recurso, a menos que você o use.


2

De acordo com Alistair Cockburn, a subtipagem não pode ser garantida em um ambiente reflexivo .

A reflexão é mais relevante para os sistemas de digitação latente. No C ++, você sabe qual o seu tipo e o que pode fazer com ele.


De um modo mais geral, a capacidade de verificar a existência de um recurso que não existe sem a introdução de Comportamento indefinido torna possível que a adição desse recurso a uma versão posterior de uma classe altere o comportamento bem definido de programas pré-existentes e consequentemente, torna impossível garantir que a adição desse recurso não "interrompa" algo.
supercat

2

A reflexão pode ser opcional, como uma diretiva de pré-processador. Algo como

#pragma enable reflection

Dessa forma, podemos ter o melhor dos dois mundos, sem essas bibliotecas de pragma criadas sem reflexão (sem nenhuma sobrecarga, conforme discutido), então seria o desenvolvedor individual se eles queriam velocidade ou facilidade de uso.


2

Se C ++ pudesse ter:

  • dados do membro da classe para nomes de variáveis, tipos de variáveis ​​e o constmodificador
  • um iterador de argumentos de função (apenas posição em vez de nome)
  • dados do membro da classe para nomes de funções, tipo de retorno e o constmodificador
  • lista de classes pai (na mesma ordem que definida)
  • dados para membros do modelo e classes pai; o modelo expandido (o que significa que o tipo real estaria disponível para a API de reflexão e não as 'informações do modelo de como chegar lá')

Isso seria suficiente para criar bibliotecas muito fáceis de usar no cerne do processamento de dados sem tipo que é tão prevalecente nos aplicativos atuais da Web e de banco de dados (todos os orms, mecanismos de mensagens, analisadores xml / json, serialização de dados etc.).

Por exemplo, as informações básicas suportadas pela Q_PROPERTYmacro (parte do Qt Framework) http://qt.nokia.com/doc/4.5/properties.html expandidas para abranger os métodos de classe ee) - seriam extraordinariamente benéficas para C ++ e para a comunidade de software em geral.

Certamente, a reflexão a que me refiro não abrangeria o significado semântico ou questões mais complexas (como comentários nos números das linhas de código-fonte, análise de fluxo de dados etc.) - mas também não acho que essas sejam necessárias para fazer parte de um padrão de linguagem.


@ Vlad: Sim, se adicionarmos recursos que suportam reflexão ao idioma, você terá reflexo no idioma. É provável que isso aconteça se o comitê de idiomas o decretar, e acho que não o fizeram a partir de 2011, e duvido que haja outro padrão de C ++ antes de 2020 AD. Então, bom pensamento. Enquanto isso, se você quiser progredir, provavelmente precisará sair do C ++.
perfil completo de Ira Baxter


0

Reflexão em C ++, acredito ser de importância crucial se o C ++ for usado como uma linguagem para acesso ao banco de dados, manipulação de sessões da Web / http e desenvolvimento de GUI. A falta de reflexão impede ORMs (como Hibernate ou LINQ), analisadores XML e JSON que instancinam classes, serialização de dados e muitos outros thigns (onde dados inicialmente sem texto devem ser usados ​​para criar uma instância de uma classe).

Uma opção de tempo de compilação disponível para um desenvolvedor de software durante o processo de compilação pode ser usada para eliminar essa preocupação de 'você paga pelo que usa'.

Como um desenvolvedor de empresa não precisa da reflexão para ler dados de uma porta serial - então não use o switch. Mas, como desenvolvedor de banco de dados que deseja continuar usando C ++, sou constantemente escalado para criar um código horrível e difícil de manter que mapeia dados entre membros de dados e construções de banco de dados.

Nem a serialização Boost nem outro mecanismo estão realmente resolvendo a reflexão - ela deve ser feita pelo compilador - e, uma vez feito, o C ++ será novamente estudado nas escolas e usado em software que lida com processamento de dados

Para mim, esta edição nº 1 (e as primitivas ingênuas de segmentação são a edição nº 2).


4
Quem disse que C ++ é para ser usado como uma linguagem para DB Access, hnadling sessão Web ou dev gui? Existem muitas linguagens muito melhores para usar nesse tipo de coisa. E uma mudança no tempo de compilação não resolverá o problema. Normalmente, a decisão de ativar ou desativar a reflexão não será feita por arquivo. Poderia funcionar se pudesse ser ativado em tipos individuais. Se o programador puder especificar com um atributo ou semelhante ao definir um tipo, se os metadados de reflexão para ele devem ou não ser gerados. Mas uma mudança global? Você estaria paralisando 90% da linguagem apenas para tornar 10% mais simples.
jalf

Então, se eu quiser um programa que seja multiplataforma e tenha acesso a uma GUI, o que devo usar? O inflexível java swing? As janelas apenas c #? Mas a verdade deve ser dita, e a verdade é que existem muitos programas que são compilados em código executável, e oferecem uma interface GUI e acesso a bancos de dados; portanto, eles devem usar algum banco de dados e suporte a GUI ... E eles não são ' t usando QT. (deve ter sido nomeado MT (monstro kit de ferramentas))
Coyote21

11
@ Coyote21: C # não é apenas do Windows há anos. (Embora eu não seja fã do Mono, ele funciona bem o suficiente para a maioria das coisas.) E o Swing não é o único kit de ferramentas da GUI para Java. Para dizer a verdade, qualquer um deles seria uma escolha melhor se você quiser entre plataformas. O C ++ sempre terá partes específicas da plataforma aqui ou ali, se você estiver fazendo algo não trivial.
precisa

Não há razão para você precisar de reflexão para o ORM. Você pode conseguir tudo isso com modelos. Há várias estruturas que fornecem ORM para C ++.
MrFox 06/07/12

0

É basicamente porque é um "extra opcional". Muitas pessoas escolhem C ++ em vez de linguagens como Java e C # para que tenham mais controle sobre a saída do compilador, por exemplo, um programa menor e / ou mais rápido.

Se você optar por adicionar reflexão, existem várias soluções disponíveis .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.