Vous êtes sur la page 1sur 15

Generic Algorithms

(TIC++V2:C6)

Yingcai Xiao 07/07/2008

What we are trying to achieve?


To be able to write an algorithm that works with any type. Makes programs both simpler and safer. To customize algorithms at runtime. Standard Template Library (STL), a subset of the Standard C++ library, was originally designed around generic algorithms. Generic algorithms are code that process sequences of any type of values in a type-safe manner. The generic algorithms in the standard library provide a vocabulary with which to describe solutions. The goal is to use predefined algorithms for almost every task, instead of hand-coding loops every time you need to process a collection of data. To achieve this goal, we have to follow certain standards to create new types.

Function Templates (TIC++V2C5)


A function template describes a family of functions. The syntax for creating either type of template is virtually identical, but they differ somewhat in how they are used. With function templates you can often omit the template arguments.

Function Template Example

template<typename T> const T& min(const T& a, const T& b) { return (a < b) ? a : b; } int z = min<int>(i, j);

int z = min(i, j);


double z = min(x, j); // x is a double

Function Template Example

#include <string> #include <sstream>

template<typename T> T fromString(const std::string& s) { std::istringstream is(s); T t; is >> t; return t; }


template<typename T> std::string toString(const T& t) { std::ostringstream s; s << t; return s.str(); } These function templates provide conversions to and from std::string for any types that provide a stream inserter or extractor, respectively.

StringConv.h

Function Template Example

int main() { int i = 1234; cout << "i == \"" << toString(i) << "\"" << endl; float x = 567.89; cout << "x == \"" << toString(x) << "\"" << endl; complex<float> c(1.0, 2.0); cout << "c == \"" << toString(c) << "\"" << endl; cout << endl; i = fromString<int>(string("1234")); cout << "i == " << i << endl; x = fromString<float>(string("567.89")); cout << "x == " << x << endl; c = fromString<complex<float> >(string("(1.0,2.0)")); cout << "c == " << c << endl;

StringConvTest.cpp

Function Template Example

The output is what youd expect: i == "1234" x == "567.89" c == "(1,2)" i == 1234 x == 567.89 c == (1,2)

Function Template Example

template<typename R, typename P> R implicit_cast(const P& p) { return p; } int main() { int i = 1; float x = implicit_cast<float>(i); int j = implicit_cast<int>(x); //! char* p = implicit_cast<char*>(i); } ///:~

Generic Algorithms

Generic Algorithms : copy

#include <algorithm> #include <cassert> #include <cstddef> // For size_t using namespace std; int main() { int a[] = { 10, 20, 30 }; const size_t SIZE = sizeof a / sizeof a[0]; int b[SIZE]; copy(a, a + SIZE, b); for(size_t i = 0; i < SIZE; ++i) assert(a[i] == b[i]); } ///:~

CopyInts.cpp

Generic Algorithms : copy

#include <algorithm> #include <cassert> #include <cstddef> #include <string> using namespace std; int main() { string a[] = {"read", "my", "lips"}; const size_t SIZE = sizeof a / sizeof a[0]; string b[SIZE]; copy(a, a + SIZE, b); // deep copy, new strings are creared assert(equal(a, a + SIZE, b)); } ///:~

CopyStrings.cpp

Generic Algorithms : copy

size_t: size for any types of varaibles. sizeof: operator to compute the size (number of elements) of an array. copy is defined as a generic algorithm. assert(): design by contract copy anything Predicate: remove_copy_ifremove_copy_if

Generic Algorithms : copy

template<typename T> void copy(T* begin, T* end, T* dest) { while(begin != end) *dest++ = *begin++;

Generic Algorithms : CopyVector.cpp

#include <algorithm> #include <cassert> #include <cstddef> #include <vector> using namespace std; int main() { int a[] = { 10, 20, 30 }; const size_t SIZE = sizeof a / sizeof a[0]; vector<int> v1(a, a + SIZE); vector<int> v2(SIZE); copy(v1.begin(), v1.end(), v2.begin()); assert(equal(v1.begin(), v1.end(), v2.begin())); } ///:~

CopyVector.cpp

Generic Algorithms : Predicates

#include <algorithm> #include <cstddef> #include <iostream> using namespace std; // You supply this predicate bool gt15(int x) { return 15 < x; } int main() { int a[] = { 10, 20, 30 }; const size_t SIZE = sizeof a / sizeof a[0]; int b[SIZE]; int* endb = remove_copy_if(a, a+SIZE, b, gt15); int* beginb = b; while(beginb != endb) cout << *beginb++ << endl; // Prints 10 only } ///:~

CopyInts2.cpp

Vous aimerez peut-être aussi