Você está na página 1de 5

Por qu usar templates ?

| Simply C++

http://simplycpp.com/2015/09/18/por-que-usar-templates/

Simply C++
C++ Moderno para o Mundo Real

Por qu usar templates ?


18 de setembro de 2015 ~ Thiago Massari ~
Se voc no est usando templates com C++, voc est perdendo toda a diverso.
A linguagem C++, apesar de suportar orientao a objetos, diferentemente de Java, no te obriga a
us-la. Voc poder ter o melhor dos mundos, em termos dos paradigmas e idiomas. Um pouco de
orientao a objetos aqui e programao genrica ali, tudo isto no mesmo cdigo!
Vamos fazer uma implementao do seguinte cdigo:
1 string_builder s;
2 s.add(1).add(12.2).add("thiago ").add(true);
3 cout << s.str() << endl;
view raw templ.cpp hosted with
by GitHub
Primeiro uma implementao tipicamente orientada a objetos pode ser:
1
2
3
4
5
6
7
8
9
10
11
12
13
1 de 14
5

class string_builder {
//...
string_builder &add(int v) {
std::string s = std::to_string(v);
_check_size(s.size());
_s += s;
return *this;
}
string_builder &add(const std::string &v) {
_check_size(v.size());
_s += v;
return *this;
}
string_builder &add(const char *v) {

9/24/15, 12:00 AM

Por qu usar templates ? | Simply C++

http://simplycpp.com/2015/09/18/por-que-usar-templates/

15
_check_size(strlen(v));
16
_s += v;
17
return *this;
18
}
19
string_builder &add(double v) {
20
std::string s = std::to_string(v);
21
_check_size(s.size());
22
_s += s;
23
return *this;
24
}
25
string_builder &add(bool v) {
26
std::string s = v?"Y":"N";
27
_check_size(s.size());
28
_s += s;
29
return *this;
30
}
31
32
//There are much more methods to implement
33
//string_builder &add(unsigned int v);
34
//string_builder &add(float v);
35
//string_builder &add(long long v);
36
//string_builder &add(unsigned long long v);
37
//.... And much more ....
view raw templ.cpp hosted with
by GitHub
Vejam s que em uma nica classe, para ser de propsito geral e suportar diversos tipos, foram
implementados os mtodos:

1:#string_builder#&add(int#v)
2:#string_builder#&add(const#std::string#&v)
3:#string_builder#&add(const#char#*v)
4:#string_builder#&add(double#v)
5:#string_builder#&add(bool#v)
6:#string_builder#&add(unsigned#int#v)
7:#string_builder#&add(float#v)
8:#string_builder#&add(long#long#v)
9:#string_builder#&add(unsigned#long#long#v)
//Faltando#ainda#short/char/etc

Para uma simples concatenao, temos estas vrias implementaes, todas quase iguais.
Agora vamos ao template.

2 de 5

9/24/15, 12:00 AM

Por qu usar templates ? | Simply C++

http://simplycpp.com/2015/09/18/por-que-usar-templates/

O que ele faz ?


O cdigo com template s existe quando instanciado, ou seja, ele completamente genrico.
Vamos fazer essa implementao de forma templatizada:
1
struct string_builder {
2
/...
3
template<typename T>
4
string_builder &add(T v) {
5
internal::add<T>(_s, v, _size);
6
return *this;
7 }
8
9 namespace internal {
10
//General implementation
11
template <typename T>
12
struct add {
13
add(std::string &buffer, T val, int size_inc) {
14
std::string s = std::to_string(val);
15
_check_size(buffer, s.size(), size_inc);
16
buffer += s;
17
}
18 };
view raw templ.cpp hosted with
by GitHub
Bem mais sucinto, no acha ?
Quando o add for chamado, o T ser substitudo pelo tipo concreto. No caso da chamada s.add(1), ser
gerado:
1 string_builder &add(int v) { -> [T = int]
2
internal::add<int>(_s, v, _size);
3
return *this;
4 }
view raw templ.cpp hosted with
by GitHub
No entanto, pode surgir a seguinte pergunta: E se eu quiser fazer um tratamento para algum caso
especfico ? ai que o template fica ainda mais interessante.
O template tem uma caracterstica muito interessante chamada especializao. Neste caso, definido o caso
genrico com T, e tambm todos os casos especficos, onde um determinado tipo ter seu tratamento
diferenciado. Por exemplo, possvel adicionar um bool, e ao invs dele virar 0 ou 1, ele seja projetado
com Y ou N, para true e false respectivamente.
A especializao ficaria assim:
1

3 de 5

template <>

9/24/15, 12:00 AM

Por qu usar templates ? | Simply C++

http://simplycpp.com/2015/09/18/por-que-usar-templates/

2 struct add<bool> {
3
add(std::string &buffer, bool val, int size_inc) {
4
string s = val?"Y":"N";
5
_check_size(buffer, s.size(), size_inc);
6
buffer += s;
7
}
8 };
view raw templ.cpp hosted with
by GitHub
E vendo a forma genrica, podemos pensar: Como eu fao para ele tratar o meu prprio tipo ? Se fosse
orientado a objetos, seria necessrio alterar a classe ou criar uma classe que herdasse dela e us-la. Isso
seria algo do tipo:
1 class my_string_builder : public string_builder {
2 //...
3
string_builder &add(MyClass &v) {
view raw templ.cpp hosted with
by GitHub
Porm, ao invs de fazer isso, podemos simplesmente usar uma especializao de template.
1 //Now I can add my own class to this string_builder add function
2 struct LazyMessage {
3
std::string type;
4
int seq;
5
std::vector<std::string> entries;
6 };
7
8 namespace Text {
9 namespace internal {
10
template <>
11
struct add<LazyMessage> {
12
add(std::string &buffer, LazyMessage &msg, int size_inc) {
13
std::string s = msg.type;
14
for(const auto &entry : msg.entries)
15
s += " [" + entry + "]";
16
_check_size(buffer, s.size(), size_inc);
17
buffer += s;
18
}
19
};
20 } //Namespace internal
21 } //Namespace Text
view raw templ.cpp hosted with
by GitHub
Desta forma o cdigo, alm de elegante e sucinto, ficar bem flexvel, rpido e divertido.
9/24/15, 12:00 AM
Parece at que est sendo escrito um cdigo em uma linguagem como Python onde o tipo sempre

4 de 5

Por qu usar templates ? | Simply C++

http://simplycpp.com/2015/09/18/por-que-usar-templates/

inferido.
Fontes:
https://github.com/SimplyCpp/examples/blob/master/templ_oo.cpp (https://github.com
/SimplyCpp/examples/blob/master/templ_oo.cpp)
https://github.com/SimplyCpp/examples/blob/master/templ.cpp (https://github.com/SimplyCpp
/examples/blob/master/templ.cpp)
Ocasionalmente, alguns dos seus visitantes podem ver um anncio aqui.
Conte mais (http://wordpress.com/about-these-ads/) | Ignorar esta mensagem

Esse post foi publicado em beginner_intermediate e marcado application programming, generic


programming, ood, template. Guardar link permanente.
Blog no WordPress.com. ~ O tema Panel.

5 de 5

9/24/15, 12:00 AM