<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>0xc0de</title>
	<atom:link href="http://0xc0de.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://0xc0de.wordpress.com</link>
	<description>Computadores, Programação e TI. Divagações...</description>
	<lastBuildDate>Sat, 17 Oct 2009 13:51:25 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>pt-br</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='0xc0de.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/10165aa27c95d0f8c0e71096d8218135?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>0xc0de</title>
		<link>http://0xc0de.wordpress.com</link>
	</image>
			<item>
		<title>Opções para leitura de um arquivo inteiro</title>
		<link>http://0xc0de.wordpress.com/2009/10/17/opcoes-para-leitura-de-um-arquivo-inteiro/</link>
		<comments>http://0xc0de.wordpress.com/2009/10/17/opcoes-para-leitura-de-um-arquivo-inteiro/#comments</comments>
		<pubDate>Sat, 17 Oct 2009 13:51:25 +0000</pubDate>
		<dc:creator>0xc0de</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[arquivos]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[IOStreams]]></category>
		<category><![CDATA[stl]]></category>
		<category><![CDATA[strings]]></category>

		<guid isPermaLink="false">http://0xc0de.wordpress.com/?p=323</guid>
		<description><![CDATA[Então, quais são as opções para lermos um arquivo inteiro para memória (armazenando-o em uma std::string, por exemplo) em C++? O programa abaixo ilustra algumas alternativas simples.

#include &#60;iostream&#62;
#include &#60;fstream&#62;
#include &#60;sstream&#62;
#include &#60;iterator&#62;
#include &#60;string&#62;

void stringstream_read_file();
void istream_iterator_read_file();
void istreambuf_iterator_read_file();

int main()
{
  //Lê copiando o buffer file stream para o string stream.
  stringstream_read_file();

  //Lê iterando pelo stream e [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=323&subd=0xc0de&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Então, quais são as opções para lermos um arquivo inteiro para memória (armazenando-o em uma <code>std::string</code>, por exemplo) em C++? O programa abaixo ilustra algumas alternativas simples.</p>
<pre class="brush: cpp;">
#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;sstream&gt;
#include &lt;iterator&gt;
#include &lt;string&gt;

void stringstream_read_file();
void istream_iterator_read_file();
void istreambuf_iterator_read_file();

int main()
{
  //Lê copiando o buffer file stream para o string stream.
  stringstream_read_file();

  //Lê iterando pelo stream e fazendo extração com operator&gt;&gt;.
  istream_iterator_read_file();

  //Lê iterando diretamente pelo buffer e copiando caracteres.
  istreambuf_iterator_read_file();

  return 0;
}

void stringstream_read_file()
{
  std::ifstream fs(&quot;file.txt&quot;);
  if (!fs.good())
    std::cout &lt;&lt; &quot;Error.&quot; &lt;&lt; std::endl;
  else
  {
    std::ostringstream ss;
    ss &lt;&lt; fs.rdbuf();
    std::cout &lt;&lt; ss.str() &lt;&lt; std::endl;
  }
}

void istream_iterator_read_file()
{
  std::ifstream fs(&quot;file.txt&quot;);
  if (!fs.good())
    std::cout &lt;&lt; &quot;Error.&quot; &lt;&lt; std::endl;
  else
  {
    fs.unsetf(std::ios_base::skipws); //Para manter os espaços.
    std::string s((std::istream_iterator&lt;char&gt;(fs)), std::istream_iterator&lt;char&gt;());
    std::cout &lt;&lt; s &lt;&lt; std::endl;
  }
}

void istreambuf_iterator_read_file()
{
  std::ifstream fs(&quot;file.txt&quot;);
  if (!fs.good())
    std::cout &lt;&lt; &quot;Error.&quot; &lt;&lt; std::endl;
  else
  {
    std::string s((std::istreambuf_iterator&lt;char&gt;(fs)), std::istreambuf_iterator&lt;char&gt;());
    std::cout &lt;&lt; s &lt;&lt; std::endl;
  }
}
</pre>
<p>Outras idéias? </p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/0xc0de.wordpress.com/323/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/0xc0de.wordpress.com/323/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/0xc0de.wordpress.com/323/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/0xc0de.wordpress.com/323/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/0xc0de.wordpress.com/323/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/0xc0de.wordpress.com/323/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/0xc0de.wordpress.com/323/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/0xc0de.wordpress.com/323/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/0xc0de.wordpress.com/323/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/0xc0de.wordpress.com/323/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=323&subd=0xc0de&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://0xc0de.wordpress.com/2009/10/17/opcoes-para-leitura-de-um-arquivo-inteiro/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/965e41270dfe683efccaf4c4c26e6a14?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">0xc0de</media:title>
		</media:content>
	</item>
		<item>
		<title>Basic basic_string String Utils</title>
		<link>http://0xc0de.wordpress.com/2009/09/13/basic-basic_string-string-utils/</link>
		<comments>http://0xc0de.wordpress.com/2009/09/13/basic-basic_string-string-utils/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 01:50:01 +0000</pubDate>
		<dc:creator>0xc0de</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[algoritmos]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[programação genérica]]></category>
		<category><![CDATA[strings]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://0xc0de.wordpress.com/?p=313</guid>
		<description><![CDATA[Vários programadores C++ devem concordar que a interface do template std::basic_string [1] não é das mais ricas. Provavelmente, muitos já até criaram suas próprias funções utilitárias para lidar com strings. Eu resolvi publicar as minhas. 
A pequena coleção de algoritmos em string não é tão poderosa e completa como a Boost String Algorithms Library. Também [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=313&subd=0xc0de&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Vários programadores C++ devem concordar que a interface do template <code>std::basic_string</code> [1] não é das mais ricas. Provavelmente, muitos já até criaram suas próprias funções utilitárias para lidar com strings. Eu resolvi publicar as minhas. </p>
<p>A pequena coleção de algoritmos em string não é tão poderosa e completa como a <a href="http://www.boost.org/doc/libs/1_40_0/doc/html/string_algo.html">Boost String Algorithms Library</a>. Também não é tão genérica quanto a da Boost. Isso, por que eu assumo que todos os tipos devem ser instâncias do template <code>std::basic_string</code>. Mesmo assim, ainda podem ter situações que compensem seu uso.</p>
<ul>
<li>Se você está trabalhando com ASCII [2], há versões das funções que aceitam qualquer tipo que seja uma instância do template <code>std::basic_string</code> parametrizado com <code>char</code> e <code>std::char_traits&lt;char&gt;</code> como sendo os dois primeiros argumentos template (o alocador não importa). Essas versões não utilizam os mecanismos de localização/internacionalização de C++, mas apenas uma tabela de conversões. Normalmente, isso permite um processamento mais rápido, já que não são realizadas chamadas de métodos virtuais das classes de facets [3]. Naturalmente, para outros encodings existem versões que aceitam um <code>std::locale</code>.</li>
<li>Caso não esteja usando a Boost em sua aplicação, pode ser que não queira adicioná-la apenas por necessitar de algumas funções utilitárias para strings.</li>
</ul>
<p>Bom, uma pequena introdução sobre minha <strong>Basic <code>basic_string</code> String Utils</strong> (que na verdade é uma versão em inglês deste texto) e o download estão disponíveis em<a href="http://sites.google.com/site/ltcmelo/basic-string-utils"> meu site</a>.</p>
<p>[1] Para os que ainda não sabem, ambos os tipos <code>std::string</code> e <code>std::wstring</code> são instâncias do template <code>std::basic_string</code>.</p>
<p>[2] Me refiro ao ASCII convencional de 7 bits, e não extensões como ISO-8859-x.</p>
<p>[3] O mecanismo de internacionalização em C++ (locales) é constituído por uma coleção de templates e classes especiais chamadas de facets.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/0xc0de.wordpress.com/313/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/0xc0de.wordpress.com/313/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/0xc0de.wordpress.com/313/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/0xc0de.wordpress.com/313/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/0xc0de.wordpress.com/313/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/0xc0de.wordpress.com/313/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/0xc0de.wordpress.com/313/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/0xc0de.wordpress.com/313/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/0xc0de.wordpress.com/313/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/0xc0de.wordpress.com/313/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=313&subd=0xc0de&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://0xc0de.wordpress.com/2009/09/13/basic-basic_string-string-utils/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/965e41270dfe683efccaf4c4c26e6a14?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">0xc0de</media:title>
		</media:content>
	</item>
		<item>
		<title>Entendendo o papel de std::iterator_traits</title>
		<link>http://0xc0de.wordpress.com/2009/08/10/iterator_traits/</link>
		<comments>http://0xc0de.wordpress.com/2009/08/10/iterator_traits/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 00:38:37 +0000</pubDate>
		<dc:creator>0xc0de</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[programação genérica]]></category>
		<category><![CDATA[stl]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://0xc0de.wordpress.com/?p=293</guid>
		<description><![CDATA[Um dos fóruns de desenvolvimento C++ que mais gosto é o Codeguru. De vez em quando participo de umas discussões por lá. Semana passada, por exemplo, surgiu um assunto que costuma gerar certas dúvidas. Principalmente, para quem não é muito por dentro do design da STL.

Quais os requisitos que tornam uma classe de iteração (um [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=293&subd=0xc0de&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Um dos fóruns de desenvolvimento C++ que mais gosto é o <a href="http://codeguru.earthweb.com/forum/forumdisplay.php?f=41">Codeguru</a>. De vez em quando participo de umas discussões por lá. Semana passada, por exemplo, surgiu um assunto que costuma gerar certas dúvidas. Principalmente, para quem não é muito por dentro do design da STL.</p>
<ul>
<li>Quais os requisitos que tornam uma classe de iteração (um <em>iterator</em>) compatível com os algoritmos da STL?</li>
<li>Quais devem ser os cuidados ao implementar um algoritmo para que ele seja compatível com os iteradores da STL?</li>
</ul>
<p>Bom, as respostas são relativamente simples. Nada mirabolante. Explicações breves seguem abaixo. Mas se alguém quiser ler a discussão original do Codeguru para entender melhor o contexto, os links são <a href="http://codeguru.earthweb.com/forum/showthread.php?t=482165">este</a> e <a href="http://codeguru.earthweb.com/forum/showthread.php?t=482297">este</a>.</p>
<p>Vamos para a primeira pergunta. Talvez você tenha criado uma nova estrutura de dados e esteja implementando um iterador para ela. Ou talvez tenha apenas inventado um mecanismo de iteração específico. Por qualquer que seja o motivo, se você tem uma classe de iteração e precisa fazê-la funcionar na STL é necessário seguir algumas diretrizes.</p>
<p>Como sabemos, os iteradores da STL são responsáveis por fazer a &#8220;cola&#8221; entre os contêineres e os algoritmos. Logo, a definição dos tipos de dados sobre os quais as operações são realizadas é de responsabilidade do iterador. A STL se apoia em um template, <code>std::iterator_traits</code>, para encapsular essa informação. Sua definição é a seguinte:</p>
<pre class="brush: cpp;">
template&lt;class iterator_t&gt;
struct iterator_traits
{
  typedef typename iterator_t::difference_type difference_type;
  typedef typename iterator_t::value_type value_type;
  typedef typename iterator_t::pointer pointer;
  typedef typename iterator_t::reference reference;
  typedef typename iterator_t::iterator_category iterator_category;
};
</pre>
<p>O template <em>std::iterator_traits</em> deve possuir uma instanciação válida para todas as classes que representam iteradores, pois os algoritmos dependem dos tipos inferidos para que possam funcionar corretamente. Existem duas maneiras de fazer isso. Uma delas (normalmente recomendada) é definir os tipos acima através de <code>typedef</code>s dentro da própria classe. </p>
<pre class="brush: cpp;">
class smart_iterator
{
public:
  typedef something value_type;
  typedef something * pointer;
  //...
};
</pre>
<p>A maneira alternativa é especializar o template <code>std::iterator_traits</code> e lá fazer a definição dos tipos. Essa é exatamente a abordagem que o próprio padrão C++ adota para que ponteiros comuns funcionem como iteradores. Portanto, a especialização de <code>std::iterator_traits</code> para ponteiros já vem de fábrica.  </p>
<pre class="brush: cpp;">
//Especialização para ponteiros (existe uma similar para ponteiros de constantes).
template&lt;class T&gt;
struct iterator_traits&lt;T*&gt;
{
  typedef ptrdiff_t difference_type;
  typedef T value_type;
  typedef T* pointer;
  typedef T&amp; reference;
  typedef random_access_iterator_tag iterator_category;
};

//Especialização para sua classe.
template &lt;&gt;
struct iterator_traits&lt;smart_iterator&gt;
{
  typedef something value_type;
  typedef something * pointer;
  //...
};
</pre>
<p>Ainda não acabou. Tendo estabelecido os tipos, você precisa se certificar de que a classe de iteração <em>satisfaz</em> as <em>expressões válidas</em> do <em>conceito</em> de iterador que se deseja <em>modelar</em>. Todos os iteradores devem suportar, por exemplo, o operador de dereferenciação (<code>operator*</code>) e o operador de acesso a membro (<code>operator-&gt;</code>). Mas alguns conceitos como <a href="http://www.sgi.com/tech/stl/BidirectionalIterator.html">Bidirectional Iterator</a> ou <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a> adicionam novos requisitos. </p>
<p>A resposta para a segunda pergunta é bem intuitiva tendo-se em vista os comentários acima. Quando quiser implementar um algoritmo no estilo STL, lembre-se de dois pontos importantes:</p>
<ul>
<li>Algoritmos operam através de iteradores. Acesso aos tipos de dados devem ser sempre feitos com o auxílio de <code>std::iterator_traits</code>. Nunca acesse o tipo diretamente através do parâmetro template correspondente ao iterador.</li>
<pre class="brush: cpp;">
template &lt;class input_iterator_t&gt;
void cool_algorithm(input_iterator first, input_iterator last)
{
  //Não faça assim!
  typename input_iterator_t::value_type a; 

  //Faça assim!
  typename std::iterator_traits&lt;input_iterator_t&gt;::value_type b;

  //...
}
</pre>
<li>Deixe claro na documentação qual o conceito esperado que o iterador modele. Obviamente, utilize apenas as expressões desse conceito (ou de conceitos que ele refina). Não utilize, por exemplo, a expressão <code>--i</code> (assumindo que <code>i</code> seja um iterador) em uma implementação que espera um <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">Forward Iterator</a>, já que ela só é válida para um <a href="http://www.sgi.com/tech/stl/BidirectionalIterator.html">Bidirectional Iterator</a>.</li>
</ul>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/0xc0de.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/0xc0de.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/0xc0de.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/0xc0de.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/0xc0de.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/0xc0de.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/0xc0de.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/0xc0de.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/0xc0de.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/0xc0de.wordpress.com/293/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=293&subd=0xc0de&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://0xc0de.wordpress.com/2009/08/10/iterator_traits/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/965e41270dfe683efccaf4c4c26e6a14?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">0xc0de</media:title>
		</media:content>
	</item>
		<item>
		<title>Construtor de cópia e operador de atribuição</title>
		<link>http://0xc0de.wordpress.com/2009/06/27/construtor-de-copia-e-operador-de-atribuicao/</link>
		<comments>http://0xc0de.wordpress.com/2009/06/27/construtor-de-copia-e-operador-de-atribuicao/#comments</comments>
		<pubDate>Sat, 27 Jun 2009 18:30:21 +0000</pubDate>
		<dc:creator>0xc0de</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[operadores]]></category>

		<guid isPermaLink="false">http://0xc0de.wordpress.com/?p=274</guid>
		<description><![CDATA[Sugestão de implementação do construtor de cópia e operador de atribuição em C++:

Crie um construtor de cópia com passagem de parâmetro por referência para uma constante.
Crie um operador de atribuição com passagem de parâmetro por valor e retorno por referência.
Crie uma função membro de swap. Idealmente, que não lance exceções.
Dentro do operador de atribuição, faça [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=274&subd=0xc0de&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Sugestão de implementação do construtor de cópia e operador de atribuição em C++:</p>
<ul>
<li>Crie um construtor de cópia com passagem de parâmetro por referência para uma constante.</li>
<li>Crie um operador de atribuição com passagem de parâmetro por valor e retorno por referência.</li>
<li>Crie uma função membro de <em>swap</em>. Idealmente, que não lance exceções.</li>
<li>Dentro do operador de atribuição, faça a troca (<em>swap</em>) entre o argumento construído por cópia e o objeto apontado por <code>this</code>.</li>
</ul>
<p>Essa é uma solução elegante e sem redundâncias (considerando que todos os <em>swaps</em> estejam corretamente implementados). Além disso, não depende da verificação de auto-atribuição no <code>operator=</code>. Para detalhes relacionados a <em>exception-safety</em>, clique <a href="http://www.gotw.ca/gotw/059.htm">aqui</a>.</p>
<pre class="brush: cpp;">
class person
{
public:
    person(std::string name);
    person(person const&amp; other); //Construtor cópia.
    person &amp; operator=(person other); //Operador atribuição.

    void swap(person &amp; other) throw();

private:
    std::string name_;
    unsigned short age_;
    /* ... */
};

person::person(std::string name):
  name_(name), age_(0) /* ... */
{}

person::person(person const&amp; other):
  name_(other.name_), age_(other.age_) /* ... */
{}

person &amp; person::operator=(person other)
{
    other.swap(*this); //Troca com a cópia recebida.
    return *this;
}

void person::swap(person &amp; other) throw()
{
    name_.swap(other.name_);
    std::swap(age_, other.age_);
    /* ... */
}
</pre>
<p>Lembre que nem sempre é necessário declarar/definir esses membros para todas as classes. O código acima visa apenas ilustrar uma forma de implementação.</p>
<p align='right'>Leandro T. C. Melo</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/0xc0de.wordpress.com/274/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/0xc0de.wordpress.com/274/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/0xc0de.wordpress.com/274/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/0xc0de.wordpress.com/274/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/0xc0de.wordpress.com/274/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/0xc0de.wordpress.com/274/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/0xc0de.wordpress.com/274/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/0xc0de.wordpress.com/274/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/0xc0de.wordpress.com/274/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/0xc0de.wordpress.com/274/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=274&subd=0xc0de&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://0xc0de.wordpress.com/2009/06/27/construtor-de-copia-e-operador-de-atribuicao/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/965e41270dfe683efccaf4c4c26e6a14?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">0xc0de</media:title>
		</media:content>
	</item>
		<item>
		<title>Heap e/ou Free Store &#8211; Áreas de Memória C++</title>
		<link>http://0xc0de.wordpress.com/2009/05/24/cppmemory/</link>
		<comments>http://0xc0de.wordpress.com/2009/05/24/cppmemory/#comments</comments>
		<pubDate>Sun, 24 May 2009 16:17:20 +0000</pubDate>
		<dc:creator>0xc0de</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[memória]]></category>

		<guid isPermaLink="false">http://0xc0de.wordpress.com/?p=245</guid>
		<description><![CDATA[Alocação de memória é assunto importante em C++. No entanto, nem todo mundo sabe exatamente como as coisas acontecem. Quantos de vocês já não viram códigos carregados de new/delete em situações nas quais objetos de pilha seriam suficientes ou mais indicados?
O livro Exceptional C++ (Herb Sutter) tem vários tópicos sobre gerenciamento de memória. Inclusive, com [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=245&subd=0xc0de&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Alocação de memória é assunto importante em C++. No entanto, nem todo mundo sabe exatamente como as coisas acontecem. Quantos de vocês já não viram códigos carregados de <code>new/delete</code> em situações nas quais objetos de pilha seriam suficientes ou mais indicados?</p>
<p>O livro <a href="http://www.gotw.ca/publications/xc++.htm">Exceptional C++ (Herb Sutter)</a> tem vários tópicos sobre gerenciamento de memória. Inclusive, com uma tabelinha bem bacana que descreve as áreas de memória de um programa C++. O detalhe, talvez um pouco polêmico, é que é feita uma distinção entre o <em>heap</em> e o <em>free store</em> (espaço livre para armazenamento). Tentarei explicar.</p>
<p>Creio que todos sabem que a alocação dinâmica é mais cara que na pilha. Ou seja, o uso do <em>new</em> e <em>delete</em> implica em solicitação e devolução de memória ao sistema operacional durante execução do programa. A consequência disso é um preço, em termos de eficiência, maior do que aquele de um objeto criado por valor na pilha. Obviamente, o <em>new</em> é necessário em inúmeros casos. Mas de onde vem essa memória?</p>
<p>Provavelmente, alguns respoderam <em>heap</em>. Outros responderam <em>free store</em>. Há ainda os que dizem que ambos são exatamente a mesma coisa. Então, existe um veredito?</p>
<p>O padrão C++ não utiliza a palavra <em>heap</em> em nenhum momento com relação à memória. Esse termo só aparece no contexto da STL com a conotação da conhecida <a href="http://en.wikipedia.org/wiki/Heap_(data_structure)">estrutura de dados</a>. No que diz respeito a alocação dinâmica, está presente apenas o conceito de <em>free store</em>. É de lá que vem a memória dinâmica de um <code>new</code>. Do ponto de vista prático, porém, o <em>free store</em> normalmente corresponde justamente ao que é chamado de <em>heap</em> nos sistemas. Portanto, apesar de certa confusão (ou mal entendido), considero que a forma <strong>oficial</strong> de se refereir a origem da memória obtida por <code>new</code> seja através de <em>free store</em>. Mas também considero totalmente aceitável que o <em>heap</em> e o <em>free store</em> sejam, de fato, o mesmo lugar.</p>
<p>Uma das origens dessa confusão é que Herb Sutter menciona no livro que o <em>free store</em> é a área de memória dinâmica utilizada por <code>new/delete</code>. Enquanto que o <em>heap</em> é área de memória utilizado pelas funções <code>malloc/free</code>. Não tenho o padrão de C em minhas mãos, mas realmente gostaria de saber se ele utiliza a palavra <em>heap</em> com o significado de área de memória. Por acaso, alguém sabe?</p>
<p>De qualquer maneira, há uma <a href="http://zamanbakshifirst.blogspot.com/2007/02/c-free-store-versus-heap.html">mensagem bem esclarecedora</a> na Intenet em que Bjarne Stroustrup tenta explicar por que foi feita a distinção entre <em>heap</em> e <em>free store</em> por Herb Sutter. De acordo com ele, a idéia era simplesmente deixar claro que uma alocação feita por <code>malloc</code> é diferente de uma alocação feita por <code>new</code>, o que faz sentido total.</p>
<p>Uau&#8230; Depois de toda essa discussão deixo um breve resumo da tabela de <em>Exceptional C++</em> que descreve as 5 áreas de memória de um programa C++. A tabela detalhada também pode ser encontrada em <a href="http://www.gotw.ca/gotw/009.htm">GotW</a>.</p>
<p><b>const data</b> &#8211; Armazena literais de strings e outros valores <em>read-only</em> conhecidos em tempo de compilação, os quais duram durante toda a execução do programa.</p>
<p><b>pilha</b> &#8211; Área de variáveis automáticas.</p>
<p><b>free store</b> &#8211; Memória dinâmica alocada/liberada por <code>new/delete</code>.</p>
<p><b>heap</b> &#8211; Memória dinâmica alocada/liberada por <code>malloc/free</code>.</p>
<p><b>global/static</b> &#8211; Armazena dados globais e estáticos, os quais são inicializados quando o programa começa a executar.</p>
<p>Bom, espero ter sido útil.</p>
<p align="right">Leandro T. C. Melo</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/0xc0de.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/0xc0de.wordpress.com/245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/0xc0de.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/0xc0de.wordpress.com/245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/0xc0de.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/0xc0de.wordpress.com/245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/0xc0de.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/0xc0de.wordpress.com/245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/0xc0de.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/0xc0de.wordpress.com/245/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=245&subd=0xc0de&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://0xc0de.wordpress.com/2009/05/24/cppmemory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/965e41270dfe683efccaf4c4c26e6a14?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">0xc0de</media:title>
		</media:content>
	</item>
		<item>
		<title>DRUM &#8211; Disk Repository with Update Management</title>
		<link>http://0xc0de.wordpress.com/2009/05/12/drum/</link>
		<comments>http://0xc0de.wordpress.com/2009/05/12/drum/#comments</comments>
		<pubDate>Wed, 13 May 2009 00:57:26 +0000</pubDate>
		<dc:creator>0xc0de</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[algoritmos]]></category>
		<category><![CDATA[estruturas de dados]]></category>

		<guid isPermaLink="false">http://0xc0de.wordpress.com/?p=237</guid>
		<description><![CDATA[Este post é um pouco diferente. Ao invés de escrever sobre o assunto aqui, simplesmente encaminho o link para um artigo no CodeProject. O texto relata os meus passos e aprendizado na implementação do teste de unicidade de URLs (URL-seen test) em um web crawler. Especificamente, o foco é na técnica conhecida como DRUM (Disk [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=237&subd=0xc0de&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Este post é um pouco diferente. Ao invés de escrever sobre o assunto aqui, simplesmente encaminho o link para um <a href="http://www.codeproject.com/KB/recipes/cppdrumimplementation.aspx">artigo no CodeProject</a>. O texto relata os meus passos e aprendizado na implementação do teste de unicidade de URLs (<em>URL-seen test</em>) em um <em>web crawler</em>. Especificamente, o foco é na técnica conhecida como DRUM (<em>Disk Repository with Update Management</em>), utilizada para armazenamento de pares <em>chave/valor</em> e verificações assíncronas. Se você tem interesse no tópico e não está com muita preguiça (ou muito trabalho) neste momento, boa leitura! Ah&#8230; é claro. Sugestões são sempre bem-vindas.</p>
<p align="right">Leandro T. C. Melo</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/0xc0de.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/0xc0de.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/0xc0de.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/0xc0de.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/0xc0de.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/0xc0de.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/0xc0de.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/0xc0de.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/0xc0de.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/0xc0de.wordpress.com/237/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=237&subd=0xc0de&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://0xc0de.wordpress.com/2009/05/12/drum/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/965e41270dfe683efccaf4c4c26e6a14?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">0xc0de</media:title>
		</media:content>
	</item>
		<item>
		<title>sizeof(char) == 1 é garantido? Mas&#8230;</title>
		<link>http://0xc0de.wordpress.com/2009/04/19/sizeof/</link>
		<comments>http://0xc0de.wordpress.com/2009/04/19/sizeof/#comments</comments>
		<pubDate>Sun, 19 Apr 2009 23:45:14 +0000</pubDate>
		<dc:creator>0xc0de</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[arquitetura computadores]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[compiladores]]></category>

		<guid isPermaLink="false">http://0xc0de.wordpress.com/?p=215</guid>
		<description><![CDATA[Provavelmente, muitos programadores C++ já se depararam com certas dúvidas relacionadas ao operador sizeof. Se ainda não aconteceu com você, quem sabe este post evite potenciais dores de cabeça. Mas mesmo se tiver um histórico sobre o assunto, ainda há chances de descobrir uma curiosidade.
Considerando os tipos fundamentais de C++, algumas perguntas comuns que aparecem [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=215&subd=0xc0de&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Provavelmente, muitos programadores C++ já se depararam com certas dúvidas relacionadas ao operador <code>sizeof</code>. Se ainda não aconteceu com você, quem sabe este post evite potenciais dores de cabeça. Mas mesmo se tiver um histórico sobre o assunto, ainda há chances de descobrir uma curiosidade.</p>
<p>Considerando os tipos fundamentais de C++, algumas perguntas comuns que aparecem por aí são as seguintes: </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;- Qual o resultado de <code>sizeof(int)</code>?<br />
&nbsp;&nbsp;&nbsp;&nbsp;- <code>sizeof(long)</code> é maior do que <code>sizeof(int)</code>?<br />
&nbsp;&nbsp;&nbsp;&nbsp;- É garantido que <code>sizeof(char)</code> seja 1 (um)?</p>
<p>Apesar de estar particularmente interessado na última delas, aproveito a ocasião para esclarecer (ou relembrar) as duas primeiras. Principalmente, pois costumam ser uma surpresa para iniciantes em C++, tendo em vista que não existe uma resposta bem definida para nenhuma delas.</p>
<p>O tamanho de um <code>int</code> não é padronizado em C++. O termo <strong>definido pela implementação</strong> (<em>implementation-defined</em>) é utilizado pelo padrão para abordar situações como essa. Portanto, o resultado de <code>sizeof(int)</code> pode não ser o mesmo em plataformas/ambientes diferentes. (No caso de <code>int</code> o tamanho sugerido é aquele <em>natural</em> da arquitetura.) Em um hardware embarcado, por exemplo, pode ser 2 bytes. Já em um computador de grande porte pode ser 8 bytes.</p>
<p>Além disso, também não é correto assumir que <code>sizeof(long)</code> é maior do que <code>sizeof(int)</code>. Novamente, o padrão C++ não faz exigências quanto a isso. Basicamente, a única restrição imposta aos tipos fundamentais é de que <code>sizeof(char)</code> &lt;= <code>sizeof(short)</code> &lt;= <code>sizeof(int)</code> &lt;= <code>sizeof(long)</code>. Replico abaixo o texto oficial do ISO/IEC 14882 (2003).</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8221;<em>There are four signed integer types: “signed char”, “short int”, “int”, and “long int.” In this list, each type provides at least as much storage as those preceding it in the list.</em>&#8220;</p>
<p>A última pergunta, que também é o título do post, tem resposta positiva. Ou seja, <code>sizeof(char)</code> é sempre igual a 1 byte. No entanto, não se empolgue muito em criar códigos mirabolantes através de manipulações de bits baseados no tamanho do <code>char</code>. Apesar da garantia acima existir, o padrão C++ não define qual o número de bits que um byte possui. Novamente, o termo <em>implementation-defined</em> se aplica:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8221;<em>A byte is at least large enough to contain any member of the basic execution character set and is composed of a contiguous sequence of bits, <b>the number of which is implementation-defined</b>.</em>&#8220;</p>
<p>É claro que na maioria dos casos um byte consiste de 8 bits. (Por coincidência, me lembro de ter lido recentemente algo sobre uma plataforma na qual o byte era composto de 7 bits. Não lembro onde nem os detalhes&#8230;) Logo, talvez essa &#8220;preocupação&#8221; nao tenha tanta justificativa do ponto de vista prático. Mas de qualquer forma, o conhecimento é sempre útil!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/0xc0de.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/0xc0de.wordpress.com/215/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/0xc0de.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/0xc0de.wordpress.com/215/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/0xc0de.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/0xc0de.wordpress.com/215/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/0xc0de.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/0xc0de.wordpress.com/215/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/0xc0de.wordpress.com/215/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/0xc0de.wordpress.com/215/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=215&subd=0xc0de&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://0xc0de.wordpress.com/2009/04/19/sizeof/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/965e41270dfe683efccaf4c4c26e6a14?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">0xc0de</media:title>
		</media:content>
	</item>
		<item>
		<title>Conceitos no C++ &#8211; Tipos Associados</title>
		<link>http://0xc0de.wordpress.com/2009/04/04/conceitos-no-c-fundamentos-ii/</link>
		<comments>http://0xc0de.wordpress.com/2009/04/04/conceitos-no-c-fundamentos-ii/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 15:07:33 +0000</pubDate>
		<dc:creator>0xc0de</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[concepts]]></category>
		<category><![CDATA[programação genérica]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://0xc0de.wordpress.com/?p=192</guid>
		<description><![CDATA[Continuando a série de posts sobre conceitos (concepts) no C++0x, agora é hora de apresentar outro elemento importante. No último post, expliquei como especificar um contexto restrito no qual apenas tipos LessThanComparable (comparáveis por menor) são permitidos. Tais tipos devem suportar o operator&#60; que recebe dois parâmetros e retorna um bool. Porém, nem sempre trabalhamos [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=192&subd=0xc0de&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Continuando a série de posts sobre conceitos (<em>concepts</em>) no C++0x, agora é hora de apresentar outro elemento importante. No <a href="http://0xc0de.wordpress.com/2008/12/02/conceitos-no-c-fundamentos-i/">último post</a>, expliquei como especificar um <em>contexto restrito</em> no qual apenas tipos LessThanComparable (comparáveis por menor) são permitidos. Tais tipos devem suportar o <code>operator&lt;</code> que recebe dois parâmetros e retorna um <code>bool</code>. Porém, nem sempre trabalhamos com <em>funções associadas</em> que operam somente sobre tipos primitivos. Inclusive, em muitos casos nem sequer sabemos exatamente quais os tipos dos dados em questão. Para resolver esses e outros problemas existem os <em>tipos associados</em>.</p>
<p>O objetivo dos tipos associados é justamente introduzir abstrações pelas quais podemos suportar funções associadas de maneira natural. Para ilustrar, considere o exemplo do <a href="http://0xc0de.wordpress.com/2008/12/02/conceitos-no-c-fundamentos-i/">post anterior</a> no qual criei uma classe chamada <code>book</code>. Suponha que essa classe faça parte de uma aplicação que modela o sistema de uma livraria. Nela, todos os itens como livros, revistas, jornais ou similares são caracterizados como sendo materias de leitura.</p>
<p>A aplicação da livraria, assim como qualquer outra, possui regras de negócio que devem ser aplicadas a todos os materiais de leitura. Mas como estamos no mundo da programação genérica, ao invés de fazer com que todos eles herdem de uma classe base comum farei com que todos modelem um conceito comum, chamado <em>ReadableMaterial</em>.</p>
<p>Para que um item seja considerado um <em>ReadableMaterial</em> ele precisa <em>satisfazer</em> alguns requisitos como, por exemplo, saber o seu número de páginas. No caso da classe <code>book</code> do post anterior assumi que essa informação era armazenada em um membro do tipo <code>int</code>. No entanto, para promover um tratamento uniforme entre os variados materiais de leitura é necessário adotar uma abstração genérica que represente o tipo de dados que cada um deles utiliza para armazenar seu número de páginas. Afinal de contas, nessa aplicação hipotética, enquanto os livros utilizam um <code>int</code> os jornais e revistas utilizam um <code>short</code>. Já as enciclopédias utilizam um <code>std::size_t</code>. Além disso, pode aparecer um novo material de leitura que utilize um tipo de dados personalizado, definido pelo próprio usuário. (Lembre que isso é apenas um exemplo de caráter didático.) Portanto, a solução é especificar, além da função associada, um tipo associado ao conceito <em>ReadableMaterial</em>.</p>
<p>Uma outra informação que gostaria de ter sobre os materiais de leitura é se determinada página contém alguma ilustração. Assim como o número de páginas, esse requisito pode ser introduzido no conceito através de uma função associada. Com isso, a definição de <em>ReadableMaterial</em> fica conforme o código abaixo.</p>
<pre class="brush: cpp;">
concept ReadableMaterial &lt;typename T&gt;
{
  typename page_size_type;

  page_size_type num_pages(T const&amp;);
  bool is_illustrated_page(T const&amp;, page_size_type);
}
</pre>
<p>Agora, a próxima etapa é justamente criar mapas de conceito entre <em>ReadableMaterial</em> e as classes que o modelam, como <code>book</code>, <code>magazine</code>, <code>newspaper</code>, entre outras. Abaixo, mostro apenas para <code>book</code>, mas os outros seriam similares. Note que o conceito não requer as funções associadas <code>num_pages</code> e <code>is_illustrated_page</code> como membros do tipo modelo (que, de fato, pode ser feito). Logo, preciso realizar o mapeamento explícito dessas funções (no caso, utilizando as próprias funções membro de <code>book</code>).</p>
<pre class="brush: cpp;">
class book
{
public:
  int num_pages() const { return num_pages_; }
  bool is_illustrated_page(int page_num) const { /*...*/ }

private:
  int num_pages_;
};

concept_map ReadableMaterial&lt;book&gt;
{
  typedef int page_size_type;

  int num_pages(book const&amp; b)
  { return b.num_pages(); }

  bool is_illustrated_page(book const&amp; b, int page_num)
  { return b.is_illustrated_page(page_num); }
}
</pre>
<p>Tendo o conceito e seus respectivos modelos definidos, posso implementar uma função genérica simples que conta o número de páginas com ilustrações de um <em>ReadableMaterial</em>. Preste atenção no código e tente identificar se ainda está faltando algo nesta abordagem.</p>
<pre class="brush: cpp;">
template &lt;typename T&gt;
  requires ReadableMaterial&lt;T&gt;
ReadableMaterial&lt;T&gt;::page_size_type count_illustrated_pages(T const&amp; t)
{
  ReadableMaterial&lt;T&gt;::page_size_type count = 0;
  for (ReadableMaterial&lt;T&gt;::page_size_type i = 0; i &lt; num_pages(t); ++i)
    if (is_illustrated_page(t, i))
      ++count;
  return count;
}
</pre>
<p>Provavelmente, os leitores que já captaram a essência da programação baseada em conceitos detectaram pequenos problemas. No <a href="http://0xc0de.wordpress.com/2008/10/16/conceitos-no-c-introducao/">primeiro post</a> da série, tentei deixar claro que uma grande vantagem desse paradigma é exatamente a imposição contratual de certas regras, tanto para o autor quanto para o usuário de templates. Eu, como autor de <code>count_illustrated_pages</code>, violei parte desse contrato. O motivo é o seguinte: Informei aos usuários que tipos que modelam <em>ReadableMaterial</em> poderiam ser utilizados na função acima. Porém, em sua implementação utilizei construções sintáticas que não são requisitos desse conceito. Ou seja, <code>count_illustrated_pages</code> depende que <code>page_size_type</code> satisfaça requisitos que não são exigidos em <em>ReadableMaterial</em>. São eles:</p>
<p>- Construção a partir de um inteiro;<br />
- Comparação por menor;<br />
- Operador de pré-incremento;<br />
- Construtor de cópia;<br />
- Destrutor.</p>
<p>Esses pequenos itens não são motivo de dores de cabeça. Há uma forma simples de fazer o exemplo funcionar. Basta adicionar os requisitos acima ao tipo associado<code> page_size_type</code> de <em>ReadableMaterial</em>. Felizmente, há um conceito chamado <em>ArithmeticLike</em> no novo padrão C++ que já os encapsula. Portanto, há basicamente duas formas de contornar a situação. A primeira delas consiste de adicionar a restrição de <em>ArithmeticLike</em> sobre <code>page_size_type</code> na função <code>count_illustrated_pages</code>, conforme mostrado abaixo. (Note a notação simplificada na qual especifico T como sendo um <em>ReadableMaterial</em> ao invés de um <code>typename</code> convencional.)</p>
<pre class="brush: cpp;">
template &lt;ReadableMaterial T&gt;
  requires ArithmeticLike&lt;T::page_size_type&gt;
T::page_size_type count_illustrated_pages(T const&amp; t)
{
  T::page_size_type count = 0;
  for (T::page_size_type i = 0; i &lt; num_pages(t); ++i)
    if (is_illustrated_page(t, i))
      ++count;
  return count;
}
</pre>
<p>A segunda delas, que considero a melhor opção, é adicionar a restrição de <em>ArithmeticLike</em> sobre <code>page_size_type</code> diretamente em <em>ReadableMaterial</em>. Nesse caso, não é necessário colocar a restrição de <em>ArithmeticLike</em> sobre a função, já que agora ela é parte integral do próprio conceito.</p>
<pre class="brush: cpp;">
concept ReadableMaterial &lt;typename T&gt;
{
  typename page_size_type;

  page_size_type num_pages(T const&amp;);
  bool is_illustrated_page(T const&amp;, page_size_type);

  requires ArithmeticLike&lt;page_size_type&gt;; //Novo requisito!
}
</pre>
<p>Até a próxima!</p>
<p>                                                                                                          Leandro T. C. Melo</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/0xc0de.wordpress.com/192/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/0xc0de.wordpress.com/192/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/0xc0de.wordpress.com/192/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/0xc0de.wordpress.com/192/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/0xc0de.wordpress.com/192/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/0xc0de.wordpress.com/192/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/0xc0de.wordpress.com/192/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/0xc0de.wordpress.com/192/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/0xc0de.wordpress.com/192/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/0xc0de.wordpress.com/192/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=192&subd=0xc0de&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://0xc0de.wordpress.com/2009/04/04/conceitos-no-c-fundamentos-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/965e41270dfe683efccaf4c4c26e6a14?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">0xc0de</media:title>
		</media:content>
	</item>
		<item>
		<title>Otimização de Classe Base Vazia (EBCO)</title>
		<link>http://0xc0de.wordpress.com/2009/02/25/otimizacao-de-classe-base-vazia-ebco/</link>
		<comments>http://0xc0de.wordpress.com/2009/02/25/otimizacao-de-classe-base-vazia-ebco/#comments</comments>
		<pubDate>Wed, 25 Feb 2009 19:48:56 +0000</pubDate>
		<dc:creator>0xc0de</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[compiladores]]></category>
		<category><![CDATA[programação genérica]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://0xc0de.wordpress.com/?p=157</guid>
		<description><![CDATA[Começarei este post com trechos de código e, em seguida, farei uma pergunta. Considere o struct information abaixo. 

struct information
{
  typedef int value_type;
  value_type get_info() const { /* ... */ }
};

Notem que ele simplesmente define um tipo e uma função membro não-virtual. Assim como membros estáticos, definições de tipo e funções não-virtuais não [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=157&subd=0xc0de&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Começarei este post com trechos de código e, em seguida, farei uma pergunta. Considere o struct <code>information</code> abaixo. </p>
<pre class="brush: cpp;">
struct information
{
  typedef int value_type;
  value_type get_info() const { /* ... */ }
};
</pre>
<p>Notem que ele simplesmente define um tipo e uma função membro não-virtual. Assim como membros estáticos, definições de tipo e funções não-virtuais não ocupam espaço em uma classe. Porém, ao declarar um membro do tipo <code>information</code> no template de classe <code>simple</code>, abaixo, observamos que 4 bytes adicionais são alocados. (Utilize <code>sizeof</code> para testar.)</p>
<pre class="brush: cpp;">
template &lt;class information_t&gt;
class simple
{
public:
  simple(information_t const&amp; info, int data) :
    info_(info), data_(data)
  {}

private:
  information_t info_; //Gera 4 bytes extras em simple.
  int data_;
};

//...

simple&lt;information&gt; s(information(), 10);
</pre>
<p>Se <code>simple</code> tivesse apenas o inteiro <code>data_</code> seu tamanho seria de 4 bytes (naturalmente, considerando o ambiente que estou compilando), mas com o membro <code>info_</code> seu tamanho vai para 8 bytes. Qual a razão desse comportamento?</p>
<p>A resposta é a seguinte: O padrão C++ não permite a existência de tipos com tamanho zero, mesmo sendo <strong>classes vazias</strong> como o struct <code>information</code>. Se não acreditar, experimente criar uma classe sem absolutamente nenhum membro e verifique seu <code>sizeof</code>. Pode parecer contraditório, mas existem motivos importantes para essa restrição. Como seria, por exemplo, um array de tipos de tamanho zero? Imaginem as operações aritméticas de ponteiros sobre ele? Confuso, não?</p>
<p>Acontece que espaço desnecessário em memória é caro em determinadas aplicações. Neste mesmo blog, em um <a href="http://0xc0de.wordpress.com/2008/10/31/alinhamento-alignment-e-preenchimento-padding/">post anterior</a>, mencionei como estratégias bem conhecidas de alinhamento e preenchimento podem resultar em uso mais eficiente de espaço. Portanto, o ideal é encontrar alguma forma de contornar essa situação. No paradigma de <a href="http://www.generic-programming.org/">programação genérica</a>, por exemplo, é bastante comum classes com caraterísticas bem similares as do struct <code>information</code>. </p>
<p>Pensando nisso, os envolvidos na padronização do C++ deixaram uma &#8220;brecha&#8221; interessante. Apesar de todos os tipos serem obrigados a terem tamanho maior que zero, quando classes vazias são utilizadas como classes bases não é necessário que nenhum espaço seja alocado para elas. Obviamente, a condição vale desde que haja a garantia que a classe base vazia não seja alocada em um mesmo endereço de outros objetos, inclusive derivados da própria hierarquia. Essa estratégia é conhecida como otimização de classe base vazia, do inglês <em><strong>Empty Base Class Optimization</strong></em> (<strong>EBCO</strong>).</p>
<p>Creio que a maioria dos compiladores profissionais implementam essa otimização. Se não me engano, tanto o Microsoft Visual C++ quanto o GCC já a fazem há bastante tempo. Logo, desenvolvedores de bibliotecas C++ ricas em templates (o que não é nada raro atualmente) devem ficar atentos para as oportunidades de otimização. No caso do exemplo deste post, como poderíamos usufruir desse recurso?</p>
<p>O primeiro passo é garantir que o struct <code>information</code> seja uma classe base, eliminando, assim, o espaço desnecessário em memória. Uma alternativa é fornecer um template de classe que agregue tanto a classe vazia quanto um dado qualquer. Tal template deve herdar da classe vazia conforme o código abaixo.</p>
<pre class="brush: cpp;">
template &lt;class base_t, class data_t&gt;
struct ebco : base_t
{
  data_t data_;
  ebco(base_t const&amp; base, data_t const&amp; data) :
    base_t(base), data_(data)
  {}
};
</pre>
<p>Agora, ao invés de declarar o membro <code>info_</code> e o membro <code>data_</code>, declararamos apenas o template <code>ebco</code> parametrizado com <code>information</code> e o inteiro que representa o dado. O template de classe <code>optimized_simple</code> faz exatamente isso.</p>
<pre class="brush: cpp;">
template &lt;class information_t&gt;
class optimized_simple
{
public:
  optimized_simple(information_t const&amp; info, int data) :
    optimization_(info, data)
  {}

private:
  ebco&lt;information_t, int&gt; optimization_ ;
};
</pre>
<p>Pronto! Comparando os retornos de <code>sizeof(simple)</code> e <code>sizeof(optimized_simple)</code> obtemos 8 bytes para o primeiro e 4 bytes para o segundo. Ou seja, para esse caso específico reduzimos o tamanho de um tipo pela metade. </p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/0xc0de.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/0xc0de.wordpress.com/157/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/0xc0de.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/0xc0de.wordpress.com/157/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/0xc0de.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/0xc0de.wordpress.com/157/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/0xc0de.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/0xc0de.wordpress.com/157/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/0xc0de.wordpress.com/157/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/0xc0de.wordpress.com/157/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=157&subd=0xc0de&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://0xc0de.wordpress.com/2009/02/25/otimizacao-de-classe-base-vazia-ebco/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/965e41270dfe683efccaf4c4c26e6a14?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">0xc0de</media:title>
		</media:content>
	</item>
		<item>
		<title>Manipuladores sem Parâmetros em C++</title>
		<link>http://0xc0de.wordpress.com/2009/01/01/manipuladores-sem-parametros-em-c/</link>
		<comments>http://0xc0de.wordpress.com/2009/01/01/manipuladores-sem-parametros-em-c/#comments</comments>
		<pubDate>Thu, 01 Jan 2009 21:08:12 +0000</pubDate>
		<dc:creator>0xc0de</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[IOStreams]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://0xc0de.wordpress.com/?p=118</guid>
		<description><![CDATA[Creio que a maioria dos programadores C++ saiba que o std::cout é um objeto do tipo std::ostream. Sendo que std::ostream é nada mais do que uma definição do template de classe std::basic_ostream com o tipo char. Ou seja:

typedef basic_ostream&#60;char&#62; ostream;

Por outro lado, já não é qualquer programador que sabe o que é o std::endl que [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=118&subd=0xc0de&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Creio que a maioria dos programadores C++ saiba que o <code>std::cout</code> é um objeto do tipo <code>std::ostream</code>. Sendo que <code>std::ostream</code> é nada mais do que uma definição do template de classe <code>std::basic_ostream</code> com o tipo <code>char</code>. Ou seja:</p>
<pre class="brush: cpp;">
typedef basic_ostream&lt;char&gt; ostream;
</pre>
<p>Por outro lado, já não é qualquer programador que sabe o que é o <code>std::endl</code> que comumente acompanha um <code>std::cout</code>. Um objeto? Uma função? Afinal, o que acontece exatamente quando o compilador encontra um <code>std::endl</code>?</p>
<pre class="brush: cpp;">
std::cout &lt;&lt; &quot;Invocando um manipulador...&quot; &lt;&lt; std::endl;
</pre>
<p>Tecnicamente, o <code>std::endl</code> é um <strong>manipulador</strong> (<em>manipulator</em>). Manipuladores são &#8220;componentes&#8221; que podem ser utilizados em conjunto com os operadores de entrada e saída de stream afim de&#8230; ora, manipular o stream. Provavelmente, você conhece outros manipuladores como, por exemplo, o <code>std::boolalpha</code> ou o <code>std::flush</code>.</p>
<p>Como é implementado um manipulador? Bom, isso depende. Manipuladores que não possuem parâmetros, como os descritos no parágrafo acima, são ponteiros de funções (<em>function pointers</em>). Já os manipuladores que possuem parâmetros, como <code>std::setw()</code> e <code>std::setfill()</code>, entre outros, são simplesmente objetos de determinada classe. Nesse post, mostrarei a implementação de um manipulador simples e sem parâmetros.</p>
<p>O padrão C++ disponibiliza quatro tipos de ponteiros de funções a serem utilizados pelos manipuladores de streams. Eles são membros dos templates <code>basic_istream</code> e <code>basic_ostream</code> e são invocados por uma sobrecarga convencional dos operadores de deslocamento (<em>shift</em>): <code>operator&lt;&lt;</code> e <code>operator&gt;&gt;</code>. Lembre que a hierarquia de classes da biblioteca C++ de IOStreams começa com a classe <code>ios_base</code>. Em seguida, aparece a classe <code>basic_ios</code>, que na verdade é um template de classe parametrizado pelo tipo do caractere e <em>traits</em> de caracteres. Herdando diretamente de <code>basic_ios</code> e igualmente parametrizadas, estão os templates de classe <code>basic_istream</code> e <code>basic_ostream</code>. Abaixo, na definição parcial de <code>basic_istream</code>,  <code>charT</code> e <code>traits</code> são, respectivamente, os parâmetros correspondentes ao tipo de caractere e ao traits.</p>
<pre class="brush: cpp;">
//Namespace std naturalmente.
template &lt;class charT, class traits = char_traits&lt;charT&gt; &gt;
class basic_istream : virtual public basic_ios&lt;charT, traits&gt;
{
public:
  //...

  //Para manipuladores que acessam apenas ios_base.
  basic_istream&lt;charT,traits&gt;&amp;
  operator&gt;&gt;
  (ios_base&amp; (*pf)(ios_base&amp;));

  //Para manipuladores que acessam basic_ios.
  basic_istream&lt;charT,traits&gt;&amp;
  operator&gt;&gt;
  (basic_ios&lt;charT,traits&gt;&amp; (*pf)(basic_ios&lt;charT,traits&gt;&amp;));

  //Para manipuladores que dependem de istream.
  basic_istream&lt;charT,traits&gt;&amp;
  operator&gt;&gt;
  (basic_istream&lt;charT,traits&gt;&amp; (*pf)(basic_istream&lt;charT,traits&gt;&amp;));
};
</pre>
<p>No parágrafo anterior eu disse que são disponibilizadas sobrecargas para quatros tipos de ponteiros de função. A quarta sobrecarca é equivalente à terceira de <code>basic_istream</code> mostrada acima. Porém, ela está diponível em <code>basic_ostream</code> e é voltada para streams de saída. O importante de ser observado é que todos os tipos de ponteiros de funções recebem e retornam um stream. Portanto, qualquer função que tenha uma assinatura consistente com uma das definições pode ser usada como um manipulador. Simples, não?</p>
<p>Aqui vai, então, a implementação e utilização do meu super manipulator. Ele não faz grandes coisas. Basicamente, é um <code>std::endl</code> incrementado que, além do caractere de fim de linha, também adiciona um caractere de <em>tab</em> para a próxima linha. Seu nome é <code>endlplacet</code> (<em>end line and place tab</em>). Ainda não consegui nenhuma utilidade prática para ele&#8230;</p>
<pre class="brush: cpp;">
#include &lt;iostream&gt;

template &lt;class charT, class traits&gt;
inline std::basic_ostream&lt;charT, traits&gt;&amp;
endlplacet(std::basic_ostream&lt;charT, traits&gt;&amp; os)
{
    os.put(os.widen('\n'));
    os.put(os.widen('\t'));
    os.flush();

    return os;
}

int main()
{
    std::cout &lt;&lt; &quot;Feliz 2009,&quot; &lt;&lt; endlplacet &lt;&lt; &quot;Leandro Melo.&quot;;

    return 0;
}
</pre>
<p style="text-align:right;">Leandro T. C. Melo</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/0xc0de.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/0xc0de.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/0xc0de.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/0xc0de.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/0xc0de.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/0xc0de.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/0xc0de.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/0xc0de.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/0xc0de.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/0xc0de.wordpress.com/118/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=0xc0de.wordpress.com&blog=4499285&post=118&subd=0xc0de&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://0xc0de.wordpress.com/2009/01/01/manipuladores-sem-parametros-em-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/965e41270dfe683efccaf4c4c26e6a14?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">0xc0de</media:title>
		</media:content>
	</item>
	</channel>
</rss>