Eu tenho trabalhado por um bom tempo em manter um nível de compatibilidade com versões anteriores e anteriores em meus programas C ++, até que finalmente tive que criar um kit de ferramentas de biblioteca , que eu estou preparando para o lançamento já foi lançado. Em geral, desde que você aceite que não será "perfeito" com compatibilidade direta nem nos recursos (algumas coisas simplesmente não podem ser emuladas para frente) nem na sintaxe (você provavelmente precisará usar macros, espaços de nomes alternativos para algumas coisas), então está tudo pronto.
Há muitos recursos que podem ser emulados no C ++ 03 em um nível suficiente para uso prático - e sem todo o aborrecimento que vem com, por exemplo: Boost. Heck, mesmo a proposta de padrões C ++ para nullptr
sugere um backport C ++ 03. E há o TR1, por exemplo, para tudo o que é C ++ 11, mas tivemos visualizações há anos. Além disso, alguns recursos do C ++ 14 , como variantes de asserção, functores transparentes e optional
podem ser implementados no C ++ 03!
As únicas duas coisas que sei que não podem ser absolutamente suportadas são modelos constexpr e variáveis.
Com relação a toda a questão de adicionar coisas ao namespace std
, minha opinião é que não importa - de maneira alguma. Pense no Boost, uma das bibliotecas C ++ mais importantes e relevantes, e sua implementação do TR1: Boost.Tr1. Se você deseja melhorar o C ++, torne-o compatível com o C ++ 11 e, por definição, está transformando-o em algo que não é o C ++ 03; portanto, bloquear-se sobre um padrão que você pretende evitar ou deixar para trás é , simplesmente, contraproducente. Os puristas reclamam, mas, por definição, não é necessário se preocupar com eles.
Claro, só porque você não seguirá o (03) Padrão, afinal, não significa que você não pode tentar ou que iria alegremente sair por aí quebrando-o. Essa não é a questão. Contanto que você mantenha um controle muito cuidadoso sobre o que é adicionado ao std
espaço para nome e tenha um controle dos ambientes em que seu software é usado (por exemplo: faça testes!), Não deve haver nenhum dano intratável. Se possível, defina tudo em um espaço para nome separado e adicione apenas using
diretivas ao espaço para nome, std
para que você não adicione nada além do que "absolutamente" precisa entrar. Qual, IINM, é mais ou menos o que o Boost.TR1 faz.
Atualização (2013) : conforme a solicitação da pergunta original e vendo alguns dos comentários aos quais não posso adicionar devido à falta de repetição, aqui está uma lista dos recursos C ++ 11 e C ++ 14 e seu grau de portabilidade para C ++ 03:
nullptr
: totalmente implementável, considerando o backport oficial do Comitê; você provavelmente precisará fornecer também algumas especializações type_traits para que seja reconhecido como um tipo "nativo".
forward_list
: totalmente implementável, embora o suporte ao alocador dependa do que a implmenentação do Tr1 pode oferecer.
- Novos algoritmos (partition_copy, etc): totalmente implementável.
- Construções de contêineres a partir de sequências de chaves (por exemplo:)
vector<int> v = {1, 2, 3, 4};
: totalmente implementáveis, embora mais elaboradas do que se gostaria.
static_assert
: quase totalmente implementável quando implementado como uma macro (você só precisa ter cuidado com vírgulas).
unique_ptr
: quase totalmente implementável, mas você também precisará de suporte para chamar o código (para armazená-lo em contêineres, etc); veja o abaixo embora.
- rvalue-reference: quase totalmente implementável, dependendo de quanto você espera obter deles (por exemplo: Boost Move).
- Para cada iteração: quase totalmente implementável, a sintaxe será um pouco diferente.
- usando funções locais como argumentos (por exemplo: transformação): quase totalmente implementável, mas a sintaxe será diferente o suficiente - por exemplo, funções locais não são definidas no site de chamada, mas antes.
- operadores de conversão explícita: implementável em níveis práticos (tornando a conversão explícita), consulte " cast_cast "do Imperfect C ++ ; mas a integração com recursos de linguagem como
static_cast<>
pode ser quase impossível.
- encaminhamento de argumento: implementável em níveis práticos, conforme mencionado acima em rvalue-reference, mas você precisará fornecer N sobrecargas às suas funções usando argumentos encaminhados.
- move: implementável em níveis práticos (veja os dois acima). Obviamente, você precisaria usar contêineres e objetos modificadores para lucrar com isso.
- Alocadores com escopo definido: Não é realmente implementável, a menos que sua implementação do Tr1 possa ajudá-lo.
- tipos de caracteres multibyte: Não é realmente implementável, a menos que o Tr1 possa dar suporte a você. Mas, para o objetivo pretendido, é melhor contar com uma biblioteca projetada especificamente para lidar com o assunto, como a UTI, mesmo se estiver usando C ++ 11.
- Listas de argumentos variáveis: implementáveis com alguns aborrecimentos, preste atenção ao encaminhamento de argumentos.
noexcept
: depende dos recursos do seu compilador.
- Novas
auto
semântica e decltype
: depende de características do seu compilador - por exemplo .: __typeof__
.
- tipos de tamanho inteiro (
int16_t
, etc): depende dos recursos do seu compilador - ou você pode delegar no Portable stdint.h.
- Atributos de tipo: depende dos recursos do seu compilador.
- Lista de inicializadores: não implementável ao meu conhecimento; no entanto, se você deseja inicializar contêineres com sequências, consulte o item acima em "construções de contêineres".
- Alias de modelo: Não é implemenável ao meu conhecimento, mas é um recurso desnecessário de qualquer maneira, e tivemos
::type
modelos para sempre
- Modelos variáveis: Não implementável ao meu conhecimento; o argumento close é template padrão, o que requer N especializações etc.
constexpr
: Não implementável ao meu conhecimento.
- Inicialização uniforme: Não implementável ao meu conhecimento, mas a inicialização padrão garantida do construtor pode ser implementada, inicializada pelo valor de ala Boost.
- C ++ 14
dynarray
: totalmente implementável.
- C ++ 14
optional<>
: quase totalmente implementável, desde que o seu compilador C ++ 03 suporte configurações de alinhamento.
- Funtores transparentes C ++ 14: quase totalmente implementáveis, mas o código do seu cliente provavelmente precisará usar explicitamente, por exemplo: .:
std::less<void>
para fazê-lo funcionar.
- C ++ 14 novas variantes de asserção (como
assure
): totalmente implementável se você deseja assertivas, quase totalmente implementável se você deseja ativar arremessos.
- Extensões de tupla C ++ 14 (obter elemento de tupla por tipo): totalmente implementável, e você pode até conseguir compilar com os casos exatos descritos na proposta de recurso.
(Isenção de responsabilidade: vários desses recursos são implementados na minha biblioteca de backports C ++ que eu vinculei acima, então acho que sei do que estou falando quando digo "totalmente" ou "quase totalmente".)