Boost candy - Johan Torp

advertisement
Boost Candy
A quick introduction to some libraries
Boost?
•
•
•
•
•
Collection of C++ libraries and a community
Meant to establish best practice
Reference implementations for future C++ standards
Widely used, well tested, industrial strength code
Portable
Smart pointers library
•
•
•
•
scoped_ptr
shared_ptr
weak_ptr
intrusive_ptr
scoped_ptr
{
boost::scoped_ptr<int> ptr(new int);
...
}
class X {
private:
boost::scoped_ptr<SomeClass> iPtr;
};
boost::scoped_ptr<int> get_ptr (); //
Illegal
shared_ptr
boost::shared_ptr<int> get_ptr ()
{
boost::shared_ptr<int> local_ptr(new int);
return local_ptr;
}
{
boost::shared_ptr<int> ptr;
ptr = get_ptr();
}
shared_ptr caveats
struct C
{
boost::shared_ptr<C> mNeighbour;
};
{
boost::shared_ptr<C> a(new C), b(new C);
a->mNeighbour = b;
b->mNeighbour = a;
}
shared_ptr caveats
Consider:
call(boost::shared_ptr<Foo>(new Foo(...)),
throwing_call())
shared_ptr caveats
Always use named variables:
boost::shared_ptr<Foo> foo(new Foo(...));
call(foo, throwing_call())
weak_ptr
namespace
{
weak_ptr<SomeClass> cache;
}
shared_ptr<SomeClass> cached_get()
{
shared_ptr<SomeClass> ptr = cache.lock();
if (!ptr)
{
ptr.reset(new SomeClass(...));
cache = ptr;
}
return ptr;
}
intrusive_ptr
Interface with libraries that uses internal reference counts
Smart pointers
Don’t use shared_array and scoped_array
Use shared/scoped pointer to std::vector, boost::array
Full STL compliance
Smart pointers comparison
boost::shared_ptr
shared ownership
boost::weak_ptr
break circular ownership,
implement cache
boost::scoped_ptr
RAII
boost::intrusive_ptr
Interface 3rd party libraries
std::auto_ptr
Sole, transferable ownership
boost::optional
Some functions only sometimes return a value
double sqrt(double n)
char get_async_input()
point
polygon::get_any_point_effectively_inside(
)
boost::optional
Alternatives to cope with this:
•
•
•
•
Required pre-condition and undefined behaviour
Throw exception
Special value (i.e. zero, inf)
Return std::pair<bool, return_value>
boost::optional approach
Single-element container, contain 0 or 1 element
boost::optional example
boost::optional<double> sqrt(double n)
{
boost::optional<double> result;
if (n >= 0) result = sqrt_helper(n);
return result;
}
boost::optional<double> root = sqrt(n);
if (root) std::cout << *root;
boost::optional example
enum ChessPiece { WHITE_KING, BLACK_KING, …};
typedef std::vector< std::vector< boost::optional<ChessPiece> > >
ChessBoard;
ChessBoard board(…);
board.at(0).at(3) = WHITE_KING;
board.at(7).at(4) = BLACK_KING;
boost::optional approach
• Deep copy semantics
copies of the container implies copies of the value
• Deep relational semantics
compare container size and if match, contained value
boost::optional benefits
• Easy to read
• Intuitive value semantics – principle of least astonishment
• ==, !=, <, >, <=, >=
boost::assign purpose
Easy to fill containers
Both insert and initialize
boost::assign example
#include <boost/assign/std/vector.hpp> //
For +=
using namespace boost::assign;
{
std::vector<int> values = (-2) (-1) (0);
values += 1,2,3,4,5,6,7,8,9;
}
boost::assign example
#include <boost/assign/map_list_of.hpp>
#include <boost/assign/list_inserter.hpp>
namespace boost::assign = ba;
{
std::map<int, std::string> mapping
= ba::map_list_of (1, ”one”) (2,
”two”);
ba::insert(mapping) (3, ”three”) (4,
”four”);
}
boost::assign example
#include <boost/assign/list_inserter.hpp>
{
std::list<int> list;
boost::assign::push_front(list) (1) (2)
(3);
}
boost::assign example
#include <boost/assign.hpp>
using namespace boost::assign;
{
// 1,2,2,2,2,2,3
std::vector<int> = 1, repeat(5, 2), 3;
}
boost::assign example
std::map<std::string, std::list<int> >
numbers
= map_list_of ( ”Primes", list_of
(1)(2)(3)(5) )
( ”Zero",
list_of (0) )
( ”Odd",
list_of
(1)(3)(5)(7) );
boost::assign problems
• Compilers not supporting templates full out
• Not 100% STL compliant std-lib implementations
boost::assign work-arounds
std::vector<int> v
std::set<int> s
);
std::map<int,int> m
m );
std::stack<int> st
);
std::queue<int> q
);
= list_of(1)(2)(3).to_container( v );
= list_of(1)(2)(3)(4).to_container( s
= map_list_of(1,2)(2,3).to_container(
= list_of(1)(2)(3)(4).to_adapter( st
= list_of(1)(2)(3)(4).to_adapter( q
boost::array<int,4> a = list_of(1)(2)(3)(4).to_array( a );
Download