Conceitos (C ++) - Concepts (C++)

Os conceitos são uma extensão do recurso de modelos fornecido pela linguagem de programação C ++ . Os conceitos são chamados de predicados booleanos nos parâmetros do template, avaliados em tempo de compilação . Um conceito pode ser associado a um modelo (modelo de classe , modelo de função ou função-membro de um modelo de classe), caso em que serve como uma restrição : ele limita o conjunto de argumentos que são aceitos como parâmetros de modelo.

Originalmente datado de sugestões para C ++ 11 , a especificação dos conceitos originais foi revisada várias vezes antes de ser formalmente uma parte obrigatória do C ++ 20 .

Principais usos

Os principais usos dos conceitos são:

  • introdução de verificação de tipo na programação de modelo
  • diagnósticos de compilador simplificados para instanciações de modelos com falha
  • selecionando sobrecargas de modelo de função e especializações de modelo de classe com base nas propriedades de tipo
  • restringindo a dedução automática de tipo

Exemplo: EqualityComparable

A seguir está uma declaração do conceito "EqualityComparable" da biblioteca padrão C ++ habilitada para conceito (que é uma Especificação Técnica ISO separada, ISO / IEC DTS 21425). Este conceito é satisfeito por qualquer tipo T, de forma que para lvalores a e bdo tipo T, as expressões a==be a!=bcompilar e seus resultados são conversíveis para um tipo que satisfaça o conceito "booleano":

template<typename T>
concept EqualityComparable = requires(T a, T b) {
    { a == b } -> std::same_as<bool>;
    { a != b } -> std::same_as<bool>;
};

Um modelo de função restrito a este conceito pode ser declarado da seguinte forma:

void f(const EqualityComparable auto&); // constrained function template declaration

ou

template <EqualityComparable T>
void f(const T&); // constrained function template declaration

E pode ser chamado normalmente:

f(42); // OK, int satisfies EqualityComparable

Diagnóstico do compilador

Se um programador tentar usar um argumento de modelo que não satisfaça os requisitos do modelo, o compilador gerará um erro. Quando os conceitos não são usados, esses erros geralmente são difíceis de entender porque o erro não é relatado no contexto da chamada, mas em um contexto de implementação interno, muitas vezes profundamente aninhado, onde o tipo foi usado.

Por exemplo, requer que seus primeiros dois argumentos sejam iteradores de acesso aleatório . Se um argumento não for um iterador ou for um iterador de uma categoria diferente, ocorrerá um erro ao tentar usar seus parâmetros como iteradores bidirecionais: std::sortstd::sort

std::list<int> l = {2, 1, 3};
std::sort(l.begin(), l.end());

O diagnóstico típico do compilador sem conceitos tem mais de 50 linhas de saída, começando com uma falha ao compilar uma expressão que tenta subtrair dois iteradores:

In instantiation of 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = std::_List_iterator<int>; _Compare = __gnu_cxx::__ops::_Iter_less_iter]':
 error: no match for 'operator-' (operand types are 'std::_List_iterator<int>' and 'std::_List_iterator<int>')
 std::__lg(__last - __first) * 2,

[..]

Se forem usados ​​conceitos, o erro pode ser detectado e relatado no contexto da chamada:

error: cannot call function 'void std::sort(_RAIter, _RAIter) [with _RAIter = std::_List_iterator<int>]'
note:   concept 'RandomAccessIterator()' was not satisfied

Resolução de sobrecarga

Os conceitos podem ser usados ​​para escolher sobrecargas de template de função e especializações de template de classe com base nas propriedades de seus argumentos de template, como uma alternativa para SFINAE e despacho de tag . Se um argumento satisfaz mais de um conceito, a sobrecarga associada ao conceito mais restrito é escolhida.

Dedução de tipo

Os conceitos podem ser usados ​​em vez do marcador de posição de dedução de tipo irrestrito em declarações de variáveis ​​e tipos de retorno de função: auto

auto     x1 = f(y); // the type of x1 is deduced to whatever f returns
Sortable auto x2 = f(y); // the type of x2 is deduced, but only compiles if it satisfies Sortable

Status de implementação

Os conceitos de TS, conforme especificado na ISO / IEC TS 19217: 2015, são implementados como um recurso experimental no GCC 6 . Os conceitos do C ++ 20 são totalmente implementados no GCC 10 , MSVC 19.30 e Clang 10 .

História

Uma forma diferente de Conceitos, popularmente conhecida como "C ++ 0x Concepts", foi temporariamente aceita no documento de trabalho para C ++ 11, mas foi removida em 2009. Além dos próprios conceitos, "C ++ 0x Concepts" incluía o conceito mapas (um recurso que poderia possibilitar, por exemplo, que o conceito "Empilhar" aceitasse , mapeando automaticamente as operações "Empilhar", como operações com nomes diferentes em , como ) e axiomas (um recurso para especificar propriedades semânticas, como associatividade ou comutatividade, permitindo ao compilador tirar proveito dessas propriedades sem prova). std::vectorpush()std::vectorpush_back()

Em contraste com essa proposta abandonada, a versão C ++ 20 de Conceitos às vezes é chamada de "Conceitos Lite".

Durante a reunião do comitê de padrões C ++ em março de 2016, o grupo de trabalho de evolução decidiu mesclar Conceitos no padrão C ++ 17 de linha principal , mas a moção foi derrotada em todo o comitê.

O Concepts v1 foi incorporado ao rascunho do C ++ 20 .

A versão "The One Range" do recurso Range que depende de conceitos também foi incorporada ao C ++ 20 .

Veja também

Notas

  1. ^ "GCC 6 Release Series - Changes, New Features, and Fixes" .
  2. ^ "Suporte ao compilador C ++ (gcc)" .
  3. ^ "Suporte ao compilador C ++" .
  4. ^ "Suporte C ++ no Clang" .
  5. ^ Bjarne Stroustrup (22 de julho de 2009). "The C ++ 0x" Remove Concepts "Decision" . Dr. Dobbs .
  6. ^ Andrew Sutton (24 de fevereiro de 2013). "Conceitos Lite: Restringindo Modelos com Predicados" . isocpp.org.
  7. ^ Honermann, Tom (6 de março de 2016). "Por que a Concepts não criou o C ++ 17" . honermann.net.
  8. ^ "2017 Toronto ISO C ++ Committee Discussion Thread (Conceitos em C ++ 20; Corrotinas, intervalos e TSes de rede publicados): cpp" .

Referências

links externos