Download presentation
Presentation is loading. Please wait.
Published byKatrina Sanders Modified over 9 years ago
1
Optional?
2
Agenda Type traits intro Interface & usage Caveats
3
Why? Uninitialized variables cause lots of bugs Removes much need for 2-stage initialization of objects A cheap 0 or 1 element container Internal storage. Much preferable over scoped_ptr + heap allocation Much less bloat & faster compilation than boost::optional
4
Type traits are meta functions! is_integer ::value => true is_floating_point ::value => false alignment_of ::value => 128 remove_reference ::type => T is_same ::value => false is_convertible ::value => true Very useful when writing generic code
5
Implemented with template specialization // Default template struct is_floating_point { enum { value = false; } }; template<> struct is_floating_point { enum { value = true; } }; template<> struct is_floating_point { enum { value = true; } };
6
Useful for static dispatch, among other things.. template T my_cool_algorithm(T t) { return my_cool_algorithm_impl ::value>(t); } template T my_cool_algorithm_impl(T t); template T my_cool_algorithm_impl(T t) { // int optimized version } template T my_cool_algorithm_impl(T t) { // float optimized version }
7
Optional interface struct Nothing {}; template class Optional { Optional(); Optional(Nothing); // Note implicit Optional(const T& value); // Note implicit Optional(const Optional & copy); Optional & operator=(Nothing); Optional & operator=(const T& value); Optional & operator=(const Optional & rhs); bool isSet() const; /// @pre isSet() T& get(); const T& get() const; }; // Override placement new to allow constructing elements without copying template inline void* operator new(size_t, fb::Optional & optional); // Convenience function template const T& getValueOr(const Optional & optional, const T& defaultValue) const; template T& getValueOr(Optional & optional, T& defaultValue) const;
8
Basic usage Optional i; ASSERT(!i.isSet()); i = 23; ASSERT(i.isSet() && i.get()==23); i = Nothing(); ASSERT(!i.isSet());
9
Return from functions // C style bool sqrt(double n, double& result); Optional sqrt(double n); Client code won’t forget to check the bool All-or-nothing guarantee, can’t break output variables
10
Member variables not always valid class X { Optional m_resultCache; }; Clearer than using -1 or other "invalid values“
11
Single item container class X { Optional m_activeWeapon; }; Does not require DefaultConstructible objects No heap allocations! Uses placement new internally Useful to store RAII objects
12
Expressive interface class X { void setLookForEnemyAroundPosition( const Optional & position); const Optional & getLookForEnemyAroundPosition(); };
13
Simplifying code class Target { // Remove, use optional instead! bool isValid() const; }; void foo(Optional t); void bar(Target t); void baz(Target t); Often little code that need complexity of invalid objects Helps maintenance – expressive client code
14
Caveats in current implementation Aligned types double in size No implicit bool conversion Unnecessary branch for some types Most of them can be fixed simply
15
Aligned types double in size sizeof(Optional ) == 2 * sizeof(Vec3) For Vec3, the pad data can be used
16
No implicit bool conversion Missing safe implicit type conversion to bool if (Optional xRoot = sqrt(x))
17
Unnecessary branch for some types ~Optional() { if (!HasTrivialDestructor ::Value && m_initialized) m_storage.destruct(); } Will get C++0x features in all of our compilers soon Until then types can be registered as having a trivial, no- op destructor
18
Further reading Unit tests in OptionalTest.cpp Static tests in HasTrivialDestructor.cpp, AlignedStorage.cpp and Optional.cpp Design rationale for boost.optional http://www.boost.org/doc/libs/1_38_0/libs/optional/doc/html/boost_optional/development. html Nullable i C# http://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.