Concepts C1X?

20 views
Skip to first unread message

Thiago Adams

unread,
Feb 13, 2012, 3:07:03 PM2/13/12
to ccppbrasil

Não sei se alguem assistiu a palestra do andrei no going native? E a
do stroustrup sobre os concepts?
A proposta do "static if" tem uma interseção bem grande com concepts e
é algo bem mais simples.

Não vejo futuro nos concepts no modo como ele está pois não acho a
motivação dele suficiente boa.
Na palestra do stroustrup não se falou muito na motivação.

Já o static if a motivação é muito mais clara e alguns casos já é
usada como o enable_if.


Walter Mascarenhas

unread,
Feb 15, 2012, 1:25:44 AM2/15/12
to ccppbrasil
Thiago,

Assisti as duas palestras.

A do Stroustoup realmente indica que "concepts"
é um conceito muito abstrato e complexo, pelo
menos na generalidade com que eles querem
fazer as coisas.

Já o static if é concreto e também
pode ser muito útil. Por isso acho mais
promissor e realista.

De certa forma, concepts é uma versão
sofisticada do "where" em C#. Em C#
funciona bem porque é simples: basta
especificar que interfaces o tipo T
no generic implementa. É limpo, dá
para entender mas não é tão poderoso
quanto o sonho do Stroustroup.

No meu ver, a questão é se algo
simples como o "where" do C#
combinado com static if
já não lidaria com 90% dos casos
relevantes na prática em que
concepts se aplicariam.

Será que, ao invés de ficar sonhando
com abstrações super poderosas
mas de dificílima implementação
e especificação, não seria melhor
fazer algo não tão poderoso mas
mais acessível ao resto da
humanidade e com alguma
chance de ser implementado
de fato?

Dai sobraria tempo para pensar
também sobre uma implementação
razoável para reflection, por exemplo.

O sonho com a generalidade absoluta
e perfeita tem seu lado negativo:
templates só poderão ser
exportados de modo "perfeito",
reflexão só entrará na linguagem
quando tudo estiver "perfeito",
concepts só serão aceitos quando
pudermos lidar perfeitamente com
todos os casos concebíveis.

De perfeito em perfeito as décadas
avançam e não chegamos a
lugar algum (perfeito ou imperfeito...)

walter.

Felipe Magno de Almeida

unread,
Feb 15, 2012, 6:31:43 AM2/15/12
to ccppb...@googlegroups.com
Eu faço bastante programas com programação genérica, e posso te dizer
que concepts seria um plus absurdo em termos de especificação da API.
Enable_if é legal, mas é só um hack geralmente. Numa API genérica
você normalmente quer "habilitar" uma function template se X, você quer
é sobrecarga como qualquer outra sobrecarga, só que ao invés de
selecionar por tipos você quer selecionar por "meta-tipo" (por qual
conceito o tipo concreto dado modela).

2012/2/13 Thiago Adams <thiago...@gmail.com>:

> --
> Antes de enviar um e-mail para o grupo leia:
>                     http://www.ccppbrasil.org/wiki/Lista:AntesdePerguntar
> --~--~---------~--~----~---------------------------------~----------~--~----~
> [&] Colabore com a Pesquisa de Preferência de Conteúdo
>              para Eventos do Grupo C & C++ Brasil:
>                        http://www.surveymonkey.com/s/GBBGTXN
> ------~----~-------~---~---~---~---~----------------~------------~---------~
> [&] C & C++ Brasil - http://www.ccppbrasil.org/
> Para sair dessa lista, envie um e-mail para ccppbrasil-...@googlegroups.com
> Para mais opções, visite http://groups.google.com/group/ccppbrasil
> --~--~---------~--~----~--~-~--~---~----~-----------------~--~----------~
> Emprego & carreira:  vag...@ccppbrasil.org
> http://groups.google.com/group/dev-guys?hl=en

--
Felipe Magno de Almeida

Felipe Magno de Almeida

unread,
Feb 15, 2012, 6:32:30 AM2/15/12
to ccppb...@googlegroups.com
Desculpe responder a mim mesmo, mas tenho que corrigir:

"Numa API genérica você normalmente *não* quer "habilitar" uma function"

Faltou o não.

2012/2/15 Felipe Magno de Almeida <felipe.m...@gmail.com>:


> Eu faço bastante programas com programação genérica, e posso te dizer
> que concepts seria um plus absurdo em termos de especificação da API.
> Enable_if é legal, mas é só um hack geralmente. Numa API genérica

> você normalmente *não* quer "habilitar" uma function template se X, você quer

Thiago Adams

unread,
Feb 15, 2012, 7:40:45 AM2/15/12
to ccppbrasil


On Feb 15, 9:31 am, Felipe Magno de Almeida
<felipe.m.alme...@gmail.com> wrote:
> Eu faço bastante programas com programação genérica, e posso te dizer
> que concepts seria um plus absurdo em termos de especificação da API.
> Enable_if é legal, mas é só um hack geralmente. Numa API genérica
> você normalmente quer "habilitar" uma function template se X, você quer
> é sobrecarga como qualquer outra sobrecarga, só que ao invés de
> selecionar por tipos você quer selecionar por "meta-tipo" (por qual
> conceito o tipo concreto dado modela).

Estes casos que você citou parecem ser resolvido pelo static if. Se
você já usa o enable if então com certeza este seria um caso aonde
poderia ser usado static if sem que a sintaxe fique poluída.

Mas o static if não é apenas para tirar a poluição do enable if, pois
ele também serve em outros contextos.



Felipe Magno de Almeida

unread,
Feb 15, 2012, 8:03:57 AM2/15/12
to ccppb...@googlegroups.com
2012/2/15 Thiago Adams <thiago...@gmail.com>:

Poder usar, pode, posso inclusive resolver com enable_if e/ou traits.
Mas não resolve a API de verdade. Uma API genérica possui
conceitos e tipos que modelam esses conceitos. Como eu tenho que
fazer hoje? Eu documento o conceito (o próprio padrão faz o mesmo
com iteradores e containers por exemplo), crio traits que definem
as metafunções para acesso de meta-dados (geralmente os tipos
relacionados ao conceito). Documento como cada metafunção deve
ser estendida (specialization, overload ou sei lá como), e uso essas
meta-funções nos algoritmos. Protejo os algoritmos através de
alguma meta-função como
does_this_really_models_the_concept_I_want<T>::type::value.

Só que o problema é que nada desse código tem a ver de fato com
o conceito. Os requerimentos do conceito deveriam ser localizados
juntos (num concept), e os algoritmos não deveriam impor os
requerimentos aos seus parametros, e sim definir quais parâmetros
ele recebe e usar essa checagem dos concepts.

Existe uma diferença bem grande de:

template <RandomAccessIterator I>
I find(I first, I last, RandomAccessIterator<I>::value_type o);

E dizer:

template <typename I>
I find_ra(I first, I last, typename std::iterator_traits<I>::value_type o);

template <typename I>
I find(I first, I last, typename std::iterator_traits<I>::value_type o)
{
static if (boost::is_convertible<typename
std::iterator_traits<I>::tag,
std::random_access_iterator_tag>::type::value)
{
return find_ra(first, last, o);
}
else // provavelmente escrever na mao a sobrecarga
;
}

Na verdade, muito melhor que static if nesse caso é simplesmente usar
tags como já é feito há muito tempo. Mas
o problema aí que eu quero dizer é que os requerimentos estão nos
algoritmos (is_convertible, iterator_traits<I>::tag)
e não na definição do conceito. Por exemplo, um iterador que faça
especialização de iterator_traits e defina apenas
tag e value_type irá funcionar nesse algoritmo, mesmo que ele não seja
de fato um RandomAccessIterator.

É por isso que em C++03 (que eu uso exclusivamente ainda), eu uso
boost.concept_check. Assim eu defino o conceito:

template <typename X>
struct FooConcept
{
typedef foo_traits<X> traits;
typedef typename traits::value_type value_type;
typedef typename traits::something_type something_type;
typedef typename traits::iterator_type iterator_type;
typedef typename traits::is_foo is_foo;

BOOST_MPL_ASSERT_RELATION(is_foo::value, ==, true); // igual a
numeric_limits<X>::is_specialized

BOOST_CONCEPT_ASSERT((boost::ForwardIteratorConcept<iterator_type>));
// iterator_type in traits must be at least
// a forward iterator

BOOST_CONCEPT_USAGE(FooConcept)
{
is_convertible_to<traits::value_type>(traits::value(x));
}

template <typename To, typename From>
void is_convertible_to(From const&)
{
BOOST_MPL_ASSERT((boost::is_convertible<From, To>));
}

X x;
};

No algoritmo então eu digo:

template <typename F>
void do_something_with_foo(F f)
{
BOOST_CONCEPT_ASSERT((FooConcept<F>)); // F realmente modela FooConcept !
}

E se eu for fazer um refinement de Foo, então eu preciso criar as tags
e criar as hierarquias de tags.

Acho que dá para ver como é "capenga" esse modelo comparado com uso de concepts.

> --

P.

unread,
Feb 15, 2012, 9:39:58 AM2/15/12
to ccppb...@googlegroups.com
Em quarta-feira, 15 de fevereiro de 2012 04h25min44s UTC-2, walter escreveu:
 
  A do Stroustoup realmente indica que "concepts"
é um conceito muito abstrato e complexo, pelo
menos na generalidade com que eles querem
fazer as coisas.


Dá uma checada nas type classes do Haskell e você vai perceber que não há nada de especial nos "concepts" do Stroustrup.

A especificação é questão de tempo, assim como o segundo protótipo.

--
 P.

Thiago Adams

unread,
Feb 15, 2012, 11:21:10 AM2/15/12
to ccppbrasil

On Feb 15, 11:03 am, Felipe Magno de Almeida

...

> No algoritmo então eu digo:
>
> template <typename F>
> void do_something_with_foo(F f)
> {
>   BOOST_CONCEPT_ASSERT((FooConcept<F>)); // F realmente modela FooConcept !
>
> }
>
> E se eu for fazer um refinement de Foo, então eu preciso criar as tags
> e criar as hierarquias de tags.
>
> Acho que dá para ver como é "capenga" esse modelo comparado com uso de concepts.

No fim das contas o que você ganha em especificar estes concepts?
Qual foi a sua motivação?

E quando você diz:

// F realmente modela FooConcept !
BOOST_CONCEPT_ASSERT((FooConcept<F>));

O que é o "realmente"? É semantica?


Felipe Magno de Almeida

unread,
Feb 15, 2012, 12:43:13 PM2/15/12
to ccppb...@googlegroups.com
2012/2/15 Thiago Adams <thiago...@gmail.com>:

>
> On Feb 15, 11:03 am, Felipe Magno de Almeida
>
> ...
>
>> No algoritmo então eu digo:
>>
>> template <typename F>
>> void do_something_with_foo(F f)
>> {
>>   BOOST_CONCEPT_ASSERT((FooConcept<F>)); // F realmente modela FooConcept !
>>
>> }
>>
>> E se eu for fazer um refinement de Foo, então eu preciso criar as tags
>> e criar as hierarquias de tags.
>>
>> Acho que dá para ver como é "capenga" esse modelo comparado com uso de concepts.
>
> No fim das contas o que você ganha em especificar estes concepts?
> Qual foi a sua motivação?

O que eu ganho é que a definição do conceito é feita em um único
ponto, e o próprio código
é auto-documentável. Assim eu não preciso verificar que cada algoritmo
de fato verifica
todos os requerimentos corretamente, basta ele ter um BOOST_CONCEPT_ASSERT
daquele conceito e daí eu sei que: se o conceito estiver bem definido
em código e a
instanciação do algoritmo ocorreu sem erros, então está OK; ou o
conceito está mal
escrito e precisa ser consertado.

Também possibilita a definição de arquétipos baseado apenas no
conceito para teste
sintático dos algoritmos. Os concepts em linguagem trazem ainda mais
uma vantagem
que é a checagem automática dos algoritmos nessa última parte (AFAIK), já que
qualquer uso fora do concept no algoritmo gera um erro (novamente AFAIK).

> E quando você diz:
>
> // F realmente modela FooConcept !
> BOOST_CONCEPT_ASSERT((FooConcept<F>));
>
> O que é o "realmente"? É semantica?

É tudo que é checável do conceito. Assume-se aí que se ele definiu
foo_traits<T>::is_foo
como true, então T modela semanticamente também FooConcept. É o equivalente do
não-auto-concept (não sei como chamam atualmente).

Thiago Adams

unread,
Feb 15, 2012, 1:49:28 PM2/15/12
to ccppbrasil


On Feb 15, 3:43 pm, Felipe Magno de Almeida
<felipe.m.alme...@gmail.com> wrote:
> 2012/2/15 Thiago Adams <thiago.ad...@gmail.com>:
O checar significa verificar o depoimento do programador
sobre o tipo.

A verdade do depoimento sobre a sintaxe só revelada
na hora da instanciação certo? Se eu mentir que um circulo
é um quadrado ele vai se dar conta quando tentar pegar a
medida do lado.

E a parte da semantica não é verificada, só é descoberto se
der erro em runtime. Por exemplo, se eu mentir que um retangulo
é um quadrado e ele assumir que são lados iguais pode dar problema
na hora de calcular.

Ainda existe uma parte dos axiomas na proposta dos concepts mas
nao entendi aonde seria usado.

No slide 32 diz:

Axiom – a semantic requirement on a type, an invariant that cannot be
evaluated at compile time;
they are assumed
–like a precondition

Então para que serve? Documentação? :D
Acho (chute é claro) que isso vai acabar sendo removido da
proposta e os concepts apenas irão facilitar a vida criando
uma sintaxe melhor para traits e facilitando o uso nos templates.

Walter Mascarenhas

unread,
Feb 16, 2012, 2:05:24 AM2/16/12
to ccppbrasil

Bom dia Felipe, Thiago e Pedro,

>> Eu faço bastante programas com programação genérica, e posso te dizer
>> que concepts seria um plus absurdo em termos de especificação da API.
>> Enable_if é legal, mas é só um hack geralmente. Numa API genérica
>> você normalmente quer "habilitar" uma function template se X, você quer
>> é sobrecarga como qualquer outra sobrecarga, só que ao invés de
>> selecionar por tipos você quer selecionar por "meta-tipo" (por qual
>> conceito o tipo concreto dado modela).

Ainda preciso pensar muito sobre tudo isto, mas gostaria
de expor minhas dúvidas e pensamentos:

Concordo que concepts seriam um plus e, indo um pouco mais
longe, acho que geralmente enable_if cheira a gambiarra mesmo.
Não tem como dar outro nome para esta história de colocar
um argumento default artificial em uma função ou método
para fazer as coisas funcionarem de tal e tal forma.

Aliás, por mais que eu admire templates e o nível de elaboração
dos argumentos apresentados nesta thread, é inegável que
toda esta história de template meta programming tem um que de
gambiarra. Ainda estamos no processo de descoberta de algo muito
poderoso e não sabemos o modo limpo de fazer as coisas.

Em termos mais globais, se Modern C++ for o que está no
livro do Alexandrescu então estamos fritos. Precisamos de
algo mais sistemático, menos dependente de idéias brilhantes
(a menos, é claro, das idéias brilhantes que removam
a necessidade de idéias brilhantes :-) )

Neste sentido, concepts são um passo positivo na direção de
uma síntese que ainda vai ocorrer.

Só acho estranho falar sobre meta tipos e tentar capturar
a semantica por trás deles enquanto a linguagem não
te dá, por exemplo, a lista de classes das quais
uma classe deriva imediatamente.

Bom, são só pensamentos desorganizados. Continuem
com a conversa, está interessante.

walter.

Felipe Magno de Almeida

unread,
Feb 16, 2012, 5:11:42 AM2/16/12
to ccppb...@googlegroups.com
2012/2/16 Walter Mascarenhas <walter.ma...@gmail.com>:

>
>  Bom dia Felipe, Thiago e Pedro,

[snip]

> Só acho estranho falar sobre meta tipos e tentar capturar
> a semantica por trás deles enquanto a linguagem não
> te dá, por exemplo, a lista de classes das quais
> uma classe deriva imediatamente.

Nunca precisei disso. Num concept eu defino os requerimentos,
por exemplo quais bases precisa herdar se necessário etc. Não
preciso inspecionar o tipo nesse nível de detalhe fazendo
programação genérica, só preciso testar que o tipo passado de fato
obedece aos requerimentos. Programação genérica != metaprogramação
AFAIK. Apesar de os dois poderem se misturar, os dois podem
também conviver muito bem sozinhos, usar templates não
significa fazer metaprogramas.

> Bom, são só pensamentos desorganizados. Continuem
> com a conversa, está interessante.
>
>      walter.

[]'s

Walter Mascarenhas

unread,
Feb 16, 2012, 6:59:33 AM2/16/12
to ccppbrasil
Felipe,

sim, sim. Eu só queria dar um exemplo
de algo que a linguagem poderia oferecer
e que me parece relativamente mais
simples e básico que concepts.

Não quis dizer que é um pré requisito.

walter.





On Feb 16, 8:11 am, Felipe Magno de Almeida
<felipe.m.alme...@gmail.com> wrote:
> 2012/2/16 Walter Mascarenhas <walter.mascaren...@gmail.com>:

P.

unread,
Feb 16, 2012, 7:58:03 AM2/16/12
to ccppb...@googlegroups.com
Em quarta-feira, 15 de fevereiro de 2012 16h49min28s UTC-2, Thiago Adams escreveu:
 
E a parte da semantica não é verificada, só é descoberto se
der erro em runtime. Por exemplo, se eu mentir que um retangulo
é um quadrado e ele assumir que são lados iguais pode dar problema
na hora de calcular.


Essa "descontinuidade possível" não é diferente daquela entre a função virtual na classe raiz e a função concreta na classe folha.

O fato de uma classe participar em uma árvore de herança, por princípio, implica que a classe obedece às invariantes das classes antecessoras, e que o contrato das funções virtuais das antecessoras está cumprido.

Se o programador não garante isso, não é um defeito no mecanismo de herança.

Exemplo:

class mongo_exception : public std::exception
{
public:

char const * what () const throw () { return NULL; }

};

 
Ainda existe uma parte dos axiomas na proposta dos concepts mas
nao entendi aonde seria usado.

No slide 32 diz:

Axiom – a semantic requirement on a type, an invariant that cannot be
evaluated at compile time;
they are assumed
–like a precondition


Há esperança de que as implementações de "concepts" serão capazes, através de análise estática, de verificar no ponto de especialização inclusive os Axiom.

Se isso é viável ou não, o time do novo protótipo vai nos informar mais cedo ou mais tarde.

  http://www.generic-programming.org/software/ConceptClang/

--
 P.

P.

unread,
Feb 16, 2012, 8:25:23 AM2/16/12
to ccppb...@googlegroups.com
Em quinta-feira, 16 de fevereiro de 2012 05h05min24s UTC-2, walter escreveu:
 
Só acho estranho falar sobre meta tipos e tentar capturar
a semantica por trás deles enquanto a linguagem não
te dá, por exemplo, a lista de classes das quais
uma classe deriva imediatamente.


Não é estranho, apenas têm em mente um conjunto de interesses diferentes do convencional.

A direção tomada pelo grupo de trabalho do C++ não parece, simplesmente, a mesma direção tomada por linguagens como Java e C#. O mecanismo de reflection nessas linguagens permite coisas maravilhosas como a JPA, sem dúvida, mas exige toda uma parafernália de suporte que viola um dos princípio de design do C++: não cobrar por um mecanismo que o programa não vai usar.

Essa história de "capturar semântica" não é o cerne da proposta dos concepts; este cerne é a especificação mais rígida da conformidade entre a declaração do template e a declaração da especialização. Hoje, essa conformidade é checada de uma forma exdrúxula -- no nível das expressões -- não foi encontrado o operator + para o tipo Foo etc. A ausência de uma checagem rígida de conformidade é indesejável, e leva novatos a errarem com scanf:

int x;
scanf("digite o valor: %d", x);

Além de uma checagem de conformidade mais significativa, i.e. melhores mensagens de erro, o mecanismo de concepts permitirá sobrecarga de templates de forma mais... confortável. Hoje, truques com enable_if já permitem isso até certo ponto, mas causam o entulho da declaração do template com parâmetros que não são parâmetros. Explicar a presença de um parâmetro enable_if a um novato é missão impossível -- especialmente dez minutos depois de exigir dele clareza no código-fonte que ele escreve. Com concepts, será possível sobrecarregar templates e ao mesmo tempo solicitar clareza no código-fonte aos novatos.

E sobrecarregar templates é utilíssimo aos autores de bibliotecas genéricas, quando seus algoritmos se satisfazem com universos de valores bem genéricos mas são otimizáveis ao acrescentar uma ou outra restrição. Compare std::copy<U> se U é InputIterator versus U é T* , T é trivially copyable.

--
 P.

Walter Mascarenhas

unread,
Feb 16, 2012, 1:01:14 PM2/16/12
to ccppbrasil

Pedro,

Primeiro, realmente, melhorar as mensagens de
erros de templates é algo **MUITO** desejável e
seria ótimo se o que for implementado de concepts
fizessse isto.

Por outro lado, me parece que há sim uma tentação
de stroustup e cia de lidar com semântica também.
veja por exemplo a história do operator== ser
comutativo na palestra (isto é a == b ser
equivalente a b == a). Eu ainda continuo
na dúvida se tentar incluir este tipo de preocupação
agora é uma boa idéia (mesmo se for factível)
Talvez se houvesse foco nos aspectos que você
enfatizou a coisa andasse mais rápido.

Quanto a reflection, talvez eu esteja subestimando
a complexidade, mas não me parece que permitir
algo tipo um template que quando instanciado
levasse a uma type list com as classes bases
imediatas causaria custo adicional para quem
não quer usar: se você não está interessado
nisso então não instancie o tal template
mágico e não atrase a sua compilação
lidando com type lists. Será que não daria
para fazer algo opcional ao longo desta
linha?

walter.
> Compare std::copy<U> se U é InputIterator versus U é T* , T é *trivially
> copyable*.
>
> --
>  P.

Thiago Adams

unread,
Feb 17, 2012, 7:15:28 AM2/17/12
to ccppbrasil


On Feb 16, 10:58 am, "P." <pedro.lama...@gmail.com> wrote:
> Em quarta-feira, 15 de fevereiro de 2012 16h49min28s UTC-2, Thiago Adams
> escreveu:
>
> > E a parte da semantica não é verificada, só é descoberto se
> > der erro em runtime. Por exemplo, se eu mentir que um retangulo
> > é um quadrado e ele assumir que são lados iguais pode dar problema
> > na hora de calcular.
>
> Essa "descontinuidade possível" não é diferente daquela entre a função
> virtual na classe raiz e a função concreta na classe folha.
>
> O fato de uma classe participar em uma árvore de herança, por princípio,
> implica que a classe obedece às invariantes das classes antecessoras, e que
> o contrato das funções virtuais das antecessoras está cumprido.
...

Tinha pensando neste caso também. A interface abstrata é um contrato
de sintaxe verificado pelo compilador e um contrato de semântica
assumido pela hierarquia e documentação.
Por algum motivo eles não gostam da ideia de hierarquia para definir
um concept (slide 14). Não consegui ver qual é o substituto, pois
claramente um conceito pode estender outro.
Entendo perfeitamente os motivos de não ter uma classe base abstrata e
impor qualquer overhead, isso é até meio óbvio.
Porém acho que é possível criar um contrato de interface no C++ e uma
espécie de hierarquia sem overhead, apenas verificando a sintaxe e a
relação dos tipos.



> > Ainda existe uma parte dos axiomas na proposta dos concepts mas
> > nao entendi aonde seria usado.
>
> > No slide 32 diz:
>
> > Axiom – a semantic requirement on a type, an invariant that cannot be
> > evaluated at compile time;
> > they are assumed
> > –like a precondition
>
> Há esperança de que as implementações de "concepts" serão capazes, através
> de análise estática, de verificar no ponto de especialização inclusive os
> Axiom.
>
> Se isso é viável ou não, o time do novo protótipo vai nos informar mais
> cedo ou mais tarde.
..

Pra mim é claro que não dá para verificar se T obedece aos axiomas
declarados em tempo de compilação e inclusive em runtime. O que dá
para fazer é verificar em runtime (debug) se um caso específico de
entrada está correto e alertar o programador com assert se não
estiver. Isso se relaciona também com as pré-condições.

O que dá para fazer em tempo de compilação é assumir que a declaração
do axioma está correta e usar a informação para fazer uma otimização.
Mas geralmente a otimização já se relaciona ao tipo todo e não precisa
entrar no detalhe do axioma. Por este tipo de questão acho que essa
parte de axiomas poderia ficar de lado e os concepts poderiam ser
focados na sintaxe e também em uma relação de conjunto sem axioma
nenhum.
"Todo número natural pertence ao conjunto dos números inteiros" então
se uma função precisa de um número inteiro e passo um número natural
ela compila normalmente sem que o compilador precise ficar verificando
os axiomas da definição de cada um.

Thiago Adams

unread,
Feb 17, 2012, 7:42:25 AM2/17/12
to ccppbrasil


On Feb 16, 4:01 pm, Walter Mascarenhas <walter.mascaren...@gmail.com>
wrote:
>   Pedro,

>   Quanto a reflection, talvez eu esteja subestimando
> a complexidade, mas não me parece que permitir
> algo tipo um template que quando instanciado
> levasse a uma type list com as classes bases
> imediatas causaria custo adicional para quem
> não quer usar: se você não está interessado
> nisso então não instancie o tal template
> mágico e não atrase a sua compilação
> lidando com type lists. Será que não daria
> para fazer algo opcional ao longo desta
> linha?

Você pode perguntar se um tipo deriva de outro no C++11 . (Já é alguma
coisa)

---------------------------


Abaixo segue um exemplo de duas coisas que dá para fazer no C++11 tal
qual como ele é.

1) Fazer uma declaração (predicado) usando traits
para um tipo T. Neste exemplo responde a pergunta é um
conceito de circulo? (traits_is_circle)

2) Selecionar uma função template de acordo com o "conceito"
ou de uma forma mais direta de acordo com o predicado

3) Definir sem overhead uma relação de hierarquia que substitui
uma declaração externa de traits.


const int pi = 3.14;

//conceito de circulo
struct circle {};

//conceito de quadrado
struct square {};

//predicado que responde se eh circulo
template<class T>
struct traits_is_circle { static const bool value = false; };

//predicado que responde se eh circulo
//pela hierarquia ou pela declaracao

template <class T>
struct is_circle {
static const bool value = std::is_base_of<circle, T>::value ||
traits_is_circle<T>::value;
};

//se for circulo usa esta funcao
template<class T>
typename std::enable_if<is_circle<T>::value, double>::type
Area(const T& o)
{
return pi * o.radius() * o.radius();
}

//se for quadrado usa esta
template<class T>
typename std::enable_if<std::is_base_of<square, T>::value,
double>::type
Area(const T& o)
{
return o.side() * o.side();
}

//MyCircle é um circle de acordo com hierarquia
struct MyCircle1 : public circle
{
double radius() const { return 1.5; }
};

//MyCircle2 é um circle porque vou declarar isso
//separadamente
struct MyCircle2
{
double radius() const { return 2.0; }
};

//Aqui eu declaro que MyCircle2 também é um circle
template<>
struct traits_is_circle<MyCircle2> { static const bool value =
true; };


struct MySquare1 : public square {
double side() const { return 2.0; }
};

int main()
{
MySquare1 s1;
MyCircle1 c1;
MyCircle2 c2;
std::cout << Area(s1) << std::endl;
std::cout << Area(c1) << std::endl;
std::cout << Area(c2) << std::endl;
}

Walter Mascarenhas

unread,
Feb 18, 2012, 3:17:25 AM2/18/12
to ccppbrasil

Thiago,

Há claramente muito que pode ser feito,
usando ainda mais templates (que tem
o poder teórico de uma máquina de
Turing).

O problema porém é a complexidade e a
dificil "manunentabilidade" do monstro que
voce vai criar.

Se a linguagem oferecesse algo pronto
as coisas ficariam mais limpas e teriamos
exemplos de bom, e recomendável, design
no qual poderiamos nos inspirar.

Mas isto é outra conversa, vamos voltar
aos concepts...

walter.
Reply all
Reply to author
Forward
0 new messages