Compartilhar via


Suporte a recursos do C++11 (C++ moderno)

Este artigo descreve os recursos do C++11 no Visual C++.

Neste artigo

  • Lista de recursos 11 c + +

    • Tabela de recursos de linguagem principal

    • Tabela de recursos de linguagem principal: simultaneidade

    • Tabela de recursos de linguagem principal: C99

  • Guia para tabelas de recursos

    • Referências de Rvalue

    • Lambdas

    • decltype

    • Enums fortemente tipados/encaminhar declarado

    • Alinhamento

    • Layout padrão e tipos triviais

    • Funções usadas como padrão e excluídas

    • override e final

    • Atomics e mais

    • C99 __func__ e regras do pré-processador

  • Recursos de biblioteca padrão

Lista de recursos do C++11

O Visual C++ no Visual Studio 2010 implementou muitos recursos na especificação da linguagem principal C++11, e o Visual C++ no Visual Studio 2012 adicionou mais deles. O Visual C++ no Visual Studio 2013 expande ainda mais essa cobertura, além de oferecer suporte a alguns recursos da Biblioteca do C++14. A tabela a seguir lista os recursos da linguagem principal do C++11 e seu status de implementação no Visual C++ no Visual Studio 2010, no Visual C++ no Visual Studio 2012 e no Visual C++ no Visual Studio 2013.

Tabela de recursos da linguagem principal do C++11

Recursos da linguagem principal do C++ 11

Visual Studio 2010

Visual Studio 2012

Visual Studio 2013

Referências de Rvalue v0.1, v1.0, v2.0, v2.1, v3.0

v2.0

v2.1*

v2.1*

qualificadores ref

Não

Não

Não

Inicializadores de membro de dados não estáticos

Não

Não

Sim

Modelos Variadic v0.9, v1.0

Não

Não

Sim

Lista do inicializador

Não

Não

Sim

static_assert

Sim

Sim

Sim

auto v0.9, v1.0

v1.0

v1.0

v1.0

Direita retornam tipos

Sim

Sim

Sim

Lambdas v0.9, v1.0, v1.1

v1.0

v1.1

v1.1

decltype v1.0, v1.1

v1.0

v1.1**

v1.1

Colchetes angulares

Sim

Sim

Sim

Argumentos do modelo para modelos de função padrão

Não

Não

Sim

Expressão SFINAE

Não

Não

Não

Modelos de alias

Não

Não

Sim

Modelos extern

Sim

Sim

Sim

nullptr

Sim

Sim

Sim

Enums fortemente tipados

Parcial

Sim

Sim

Enums declarados

Não

Sim

Sim

Atributos

Não

Não

Não

constexpr

Não

Não

Não

Alinhamento

TR1

Parcial

Parcial

Delegação de construtores

Não

Não

Sim

Herdando construtores

Não

Não

Não

Operadores de conversão explícita

Não

Não

Sim

char16_t/char32_t

Não

Não

Não

Literais de cadeia de caracteres Unicode

Não

Não

Não

Literais de cadeia de caracteres bruta

Não

Não

Sim

Nomes de caractere universais em literais

Não

Não

Não

Literais definidos pelo usuário

Não

Não

Não

Layout padrão e tipos triviais

Não

Sim

Sim

Funções padronizadas e excluídas

Não

Não

Sim*

Declarações amigas estendidas

Sim

Sim

Sim

Sizeof estendido

Não

Não

Não

Namespaces embutidos

Não

Não

Não

Uniões irrestritas

Não

Não

Não

Local e sem nome tipos como argumentos de modelo

Sim

Sim

Sim

Baseado em intervalo para loop

Não

Sim

Sim

substituição e final v0.8, v0.9, v1.0

Parcial

Sim

Sim

Suporte GC mínimo

Sim

Sim

Sim

noexcept

Não

Não

Não

[ir para o início]

Tabela de recursos da linguagem principal do C++11: simultaneidade

Recursos da linguagem principal do C++11: simultaneidade

Visual Studio 2010

Visual Studio 2012

Visual Studio 2013

Pontos de sequência reformulados

N/D

N/D

N/D

Atomics

Não

Sim

Sim

Comparação e troca fortes

Não

Sim

Sim

Limites bidirecionais

Não

Sim

Sim

Modelo de memória

N/D

N/D

N/D

Ordenação de dependência de dados

Não

Sim

Sim

Ordenação de dependência de dados: anotação de função

Não

Não

Não

exception_ptr

Sim

Sim

Sim

quick_exit

Não

Não

Não

Atômicos em manipuladores de sinal

Não

Não

Não

Armazenamento local de thread

Parcial

Parcial

Parcial

Estatísticas mágicas

Não

Não

Não

[ir para o início]

Recursos da linguagem principal do C++11: C99

Recursos da linguagem principal do C++11: C99

Visual Studio 2010

Visual Studio 2012

Visual Studio 2013

__func__

Parcial

Parcial

Parcial

Pré-processador C99

Parcial

Parcial

Parcial

long long

Sim

Sim

Sim

Tipos de inteiro estendidos

N/D

N/D

N/D

[ir para o início]

Guia para as tabelas de recursos

Referências de Rvalue

Dica

As designações de versão (v0.1, v1.0, v2.0, v2.1, v3.0) nas descrições a seguir são inventadas apenas para mostrar a evolução do C++11.O padrão propriamente dito não as usa.

N1610 "Esclarecimento de inicialização de objetos de classe por rvalues" foi uma tentativa inicial de habilitar a semântica de movimento sem referências de rvalue. Para esta discussão, vamos chamá-la de "referências de rvalue v0.1". Isso foi substituído por "referências de rvalue v 1.0." "Referências de Rvalue v 2.0", que o trabalho no Visual C++ no Visual Studio 2010 foi baseado, proíbem referências de associação rvalue a lvalues e, portanto, corrige um grande problema de segurança. " Referências de Rvalue v2.1" refinam essa regra. Considere vector<string>::push_back(), que tem as sobrecargas push_back(const string&) e push_back(string&&) e a chamada v.push_back("strval"). A expressão "strval" é um literal de cadeia de caracteres e um lvalue. (Outros literais — por exemplo, o inteiro 1729, são rvalues, mas os literais de cadeia de caracteres são especiais porque são arrays.) As regras de "referências de rvalue v 2.0" disseram que string&& não é possível associar "strval" porque "strval" é um l-value e, portanto, push_back(const string&) é a única sobrecarga viável. Isso criava um std::stringtemporário, o copiava para o vetor e destruía o std::string temporário, o que não era muito eficiente. As regras de "referências de rvalue v2.1" reconhecem que a associação de string&& a "strval" criaria um std::stringtemporário e que esse temporário é um rvalue. Portanto, push_back(const string&) e push_back(string&&) são viáveis, e push_back(string&&) é preferencial. Um std::string temporário é construído e movido para o vetor. Isso é mais eficiente.

“Referências de rvalue v3.0” adicionam novas regras para gerar automaticamente construtores de movimentação e operadores de atribuição de movimentação em certas condições. No entanto, isso não é implementado no Visual C++ no Visual Studio 2013 devido às restrições de tempo e de recursos.

[ir para o início]

Lambdas

Depois que as funções lambda foram votadas no Documento de Trabalho (versão "0.9") e os lambdas mutáveis foram adicionados (versão "1.0"), o comitê de normalização revisou o texto. Isso produziu lambdas versão "1.1", que agora têm suporte total. As palavras dos lambdas v1.1 esclarecem o que deve ocorrer em casos de problemáticos, como a referência a membros estáticos ou lambdas aninhados. Isso corrige os problemas disparados por lambdas complexos. Além disso, agora os lambdas sem estado podem ser convertidos em ponteiros de função. Isso não está no texto do N2927, mas é contado como parte dos lambdas v1.1 de qualquer maneira. O C++11 5.1.2 [expr.prim.lambda]/6 tem esta descrição: "O tipo de fechamento para lambda-expression sem lambda-capture tem uma função de conversão const pública não virtual e não explícita em ponteiro com o mesmo parâmetro e tipos de retorno do operador de chamada de função do tipo de fechamento. O valor retornado por essa função de conversão deve ser o endereço de uma função que, quando invocado, tem a mesma effect como invocar o operador de chamada de função do tipo de fechamento. " (O Visual C++ no Visual Studio 2012 implementação é ainda melhor do que isso, porque torna lambdas sem estado podem ser convertidos em ponteiros de função que têm convenções arbitrárias de chamada. Isso é importante quando você usa APIs que esperam itens como ponteiros de função __stdcall.)

[ir para o início]

decltype

Depois de decltype ter sido votado no Documento de Trabalho (versão 1.0), ele recebeu uma pequena, mas importante, correção de última hora (versão 1.1). Isso é muito interessante para programadores que trabalham no STL e no Boost.

[ir para o início]

Enums fortemente tipados/encaminhar enums declarados

Enums fortemente tipados tiveram suporte parcial no Visual C++ do Visual Studio 2010 (especificamente, a parte sobre tipos subjacentes especificados explicitamente). Agora, eles têm suporte total no Visual Studio, e a semântica do C++11 para enums declarados antecipadamente também está totalmente implementada.

[ir para o início]

Alinhamento

As palavras-chave da linguagem principal alignas/alignof da proposta de alinhamento que foi votada no Documento de Trabalho não são implementadas. O Visual C++ no Visual Studio 2010 tinha aligned_storage do TR1. O Visual C++ no Visual Studio 2012 adicionou aligned_union e std::align() à Biblioteca Padrão e problemas significativos foram corrigidos no Visual C++ no Visual Studio 2013.

[ir para o início]

Layout padrão e tipos triviais

As alterações expostas de N2342 "PODs revisitados; edição de núcleo de resolução 568 (revisão 5)" são as adições de is_trivial e is_standard_layout a <type_traits> da Biblioteca de Modelos Padrão. (N2342 reformulada muitas palavras a linguagem principal, mas nenhuma alteração de compilador foi necessária). Essas características de tipo estavam disponíveis no Visual C++ no Visual Studio 2010, mas apenas duplicavam is_pod. Portanto, a tabela anterior neste documento disse "Não" ao suporte. Agora, elas são habilitadas por ganchos de compilador que são criados para fornecer respostas exatas.

O common_type<> do STL recebeu uma correção muito importante no Visual C++ no Visual Studio 2013. A especificação do C++11 para common_type<> teve consequências inesperadas e indesejadas. Em particular, ela faz common_type<int, int>::type retornar int&&. Portanto, o Visual C++ no Visual Studio 2013 implementa a Resolução proposta para problema do Grupo de Trabalho da Biblioteca 2141, que faz o common_type<int, int>::type retornar int.

Como um efeito colateral dessa alteração, o caso de identidade não funciona mais (common_type<T> sem sempre resulta no tipo T). Isso segue a resolução proposta, mas interrompe qualquer código que depende do comportamento anterior.

Se você precisar de uma característica de tipo de identidade, não use std::identity não padrão que seja definida em <type_traits> porque ela não funcionará para <void>. Em vez disso, implemente sua própria característica de tipo de identidade para atender às suas necessidades. Veja um exemplo:

template <typename T> struct Identity {
    typedef T type;
};

Dica

Para outras alterações significativas, consulte Alterações significativas do Visual C++.

[ir para o início]

Funções usadas como padrão e excluídas

Agora, elas são aceitas, mas com esta exceção: para funções usadas como padrão, não há suporte para o uso de =default para solicitar construtores de movimentação e operadores de atribuição de movimentação de membros. As cópias e as movimentações não interagem com precisão como o padrão diz que deveriam. Por exemplo, a exclusão de movimentações é especificada para também suprimir cópias, mas o Visual C++ no Visual Studio 2013 não faz isso.

Para obter informações sobre como usar funções padronizadas e excluídas, consulte Definições de função C++.

[ir para o início]

override e final

Isso passou por uma evolução curta, porém complicada. Originalmente, na versão 0.8, havia os atributos [[override]], [[hiding]] e [[base_check]]. Na versão 0.9, os atributos foram eliminados e substituídos por palavras-chave contextuais. Por fim, na versão 1.0, eles foram reduzidos para "final" em classes e "override" e "final" em funções. Isso a transforma em uma extensão ascendente porque o Visual C++ do Visual Studio 2010 já oferecia suporte a esta sintaxe "override" em funções e tinha a semântica razoavelmente próxima no C++11. " final" também possuía suporte, mas com ortografia diferente "sealed". A ortografia padrão e a semântica de "override" e "final" agora têm total suporte. Para obter mais informações, consulte substituir especificador e especificador final.

[ir para o início]

Atômicos e mais

Atômicos, comparação e troca fortes, cercas bidirecionais e ordenação de dependência de dados especificam o maquinário da Biblioteca Padrão, que agora está implementada.

Cabeçalhos STL relacionados: < atomic >, < chrono >, < condition_variable >, < futuras >, < mutex >, < taxa >, < scoped_allocator >, e < thread >.

[ir para o início]

C99 __func__ e regras do pré-processador

A tabela tabela recursos da linguagem principal: C99 implementação "Parcial para dois itens" de lista. No caso do identificador predefinido __func__, "Parcial" é listado porque é fornecido suporte às extensões não padrão __FUNCDNAME__, __FUNCSIG__ e __FUNCTION__. Para obter mais informações, consulte Macros predefinidas. No caso de regras do pré-processador C99, "Parcial" é listado porque macros variadic têm suporte. Para obter mais informações, consulte Macros variadic.

[ir para o início]

Recursos de biblioteca padrão

Isso aborda a linguagem principal. Na Biblioteca Padrão do C++11, não temos uma tabela de comparação de recursos, mas o Visual C++ no Visual Studio 2012 a implementou, com duas exceções. Primeiro, quando um recurso da biblioteca dependia de uma funcionalidade ausente no compilador, ele era simulado — por exemplo, modelos variadic simulados para make_shared<T>() — ou não era implementado. (Houve apenas alguns casos — especialmente, <initializer_list>— que agora são totalmente implementados em Visual C++ no Visual Studio 2013.) Com raras exceções, C99 foi implementado no Visual C++ no Visual Studio 2013 e cabeçalhos de wrapper do C++ fornecidos. Para obter mais informações, consulte Suporte à biblioteca C99 no Visual Studio 2013.

Veja a seguir uma lista parcial das alterações no Visual C++ no Visual Studio 2012 e no Visual C++ no Visual Studio 2013:

Posicionamento: conforme exigido pelo C++11, emplace()/emplace_front()/emplace_back()/emplace_hint()/emplace_after() são implementados em todos os contêineres para números de argumentos "arbitrários" (consulte a seção "Variadics simuladas"). Por exemplo, vector<T> tem "template <typename... Args> void emplace_back(Args&&... args)", que constrói diretamente um elemento do tipo T na parte de trás do vetor a partir de um número arbitrário de argumentos arbitrários, encaminhados perfeitamente. Isso pode ser mais eficiente do que push_back(T&&), que envolveria uma construção e destruição de movimentação adicional.

Variadics: o Visual C++ no Visual Studio 2012 tinha um esquema para simular modelos variadic. No Visual C++ no Visual Studio 2013, as simulações desapareceram e variadics são totalmente implementados. Se seu código depende do antigo comportamento do variadics simulado, será necessário corrigi-lo. No entanto, a alternância para modelos variadic reais tem tempos de compilação aprimorados e consumo reduzido de memória do compilador.

Operadores de conversão explícita: na linguagem principal, os operadores de conversão explícita são um recurso geral — por exemplo, você pode ter explicit operator MyClass(). No entanto, a Biblioteca Padrão usa atualmente apenas um formulário: explicit operator bool(), que permite testar com segurança as classes com boolianos. (Sem formatação "operator bool()" é notoriamente perigoso.) Anteriormente, o Visual C++ simulava explicit operator bool() com operator pointer-to-member(), que levaram a várias dores de cabeça e ligeiras ineficiências. Agora, essa solução alternativa de "bool falso” é removida completamente.

Aleatoriedade: uniform_int_distribution agora é perfeitamente imparcial, e shuffle() é implementado em <algorithm>, que aceita diretamente Geradores de Números Aleatórios Uniformes, como mersenne_twister.

Resistência a operadores address-of sobrecarregados: o C++98/03 proibiu um elemento de um contêiner do STL de sobrecarregar seu operador address-of. Isso é o que as classes como CComPtr fazem, de forma que as classes auxiliares como CAdapt fossem necessárias para proteger o STL dessas sobrecargas. Durante o desenvolvimento do Visual C++ no Visual Studio 2010, as alterações do STL o fizeram rejeitar operadores address-of sobrecarregados em ainda mais situações. O C++11 alterou os requisitos para tornar os operadores address-of sobrecarregados aceitáveis. O C++11 e o Visual C++ no Visual Studio 2010 fornecem a função auxiliar std::addressof(), que pode obter o endereço verdadeiro de um objeto, independentemente da sobrecarga do operador. Antes do lançamento do Visual C++ no Visual Studio 2010, tentamos substituir ocorrências de "&elem" por "std::addressof(elem)", que é adequadamente resistente. Visual C++ no Visual Studio 2012 foi mais longe, de modo que classes que sobrecarregam o operador address-of devem ser utilizadas por meio de STL.

O Visual C++ no Visual Studio 2012 foi além do C++11 em várias maneiras:

Iteradores SCARY: como são permitidos, mas não obrigatórios para o C++11 Standard, os iteradores SCARY foram implementados como descrito por N2911 "Minimizando dependências em classes genéricas para programas mais rápidos e menores" e N2980 "Atribuição e inicialização do iterador SCARY, revisão 1".

Filesystem: foi adicionado o cabeçalho <filesystem> da proposta TR2. Ele oferece recursive_directory_iterator e outros recursos interessantes. Antes que o trabalho em TR2 fosse congelado porque o C++0x estava muito atrasado e mudando para o C++11, a proposta 2006 foi derivada de Boost.Filesystem V2. Posteriormente, ele evoluiu para Boost.Filesystem V3, mas isso não é implementado no Visual C++ no Visual Studio 2012.

E uma grande otimização! Todos os nossos contêineres agora são idealmente pequenos, considerando suas representações atuais. Isso refere-se aos objetos de contêiner propriamente ditos, e não ao conteúdo apontado. Por exemplo, std::vector contém três ponteiros brutos. No Visual C++ no Visual Studio 2010, modo de versão x86, std::vector tinha 16 bytes. No Visual C++ no Visual Studio 2012, tem 12 bytes, que é idealmente pequeno. Esse é o grande negócio — se você tiver 100.000 vetores em seu programa, o Visual C++ no Visual Studio 2012 fará você economizar 400.000 bytes. O uso de menos memória economiza espaço e tempo.

Isso foi obtido evitando o armazenamento de alocadores e comparadores vazios, porque std::allocator e std::less não têm estado. (Essas otimizações são habilitadas para alocadores/comparadores personalizados também, desde que não tenham estado. Obviamente, o armazenamento de alocadores/comparadores com estado não pode ser evitado, mas eles são muito raros).

O Visual C++ no Visual Studio 2013 vai ainda mais além do C++11 para implementar alguns recursos-chave de biblioteca do C++14:

  • “Functors transparentes de operador” less<>, greater<>, plus<>, multiplies<> e assim por diante.

  • make_unique<T>(args...) e make_unique<T[]>(n)

  • Funções de não membros cbegin()/cend(), rbegin()/rend() e crbegin()/crend().

[ir para o início]

Consulte também

Referência

Expressões lambda em C++

Instrução for com base em intervalo (C++)

Conceitos

Novidades do Visual C++ no Visual Studio 2013

Alterações significativas do Visual C++

Outros recursos

Bem-vindo ao C++ (C++ moderno)

Referência de linguagem C++

Referência da Biblioteca Padrão C++

Blog da equipe do Visual C++