Programming with Qt

27 downloads 451 Views 701KB Size Report
Increase type safety. Improve performance and ability to work directly with hardware. Fit into the real world. 5/43. Introduction to C++11 and its use inside Qt  ...
Introduction to C++11 and its use inside Qt Olivier Goffart February 2013

1/43

Introduction to C++11 and its use inside Qt

About Me

http://woboq.com http://code.woboq.org

2/43

Introduction to C++11 and its use inside Qt

History 1979: 1983: 1991: 1998: 2003: 2005: 2011: 2012: 3/43

C With classes C++ Qt development begins (Qt 1.0 in 1995) C++98 - First standardized C++ C++03 - Only few corrections Qt 4.0 C++11 Qt 5.0

Introduction to C++11 and its use inside Qt

Goals of C++11 From the C++11 FAQ:

Make C++ a better language for systems programming and library building that is, to build directly on C++’s contributions to programming, rather than providing specialized facilities for a particular sub-community (e.g. numeric computation or Windows-style application development).

Make C++ easier to teach and learn through increased uniformity, stronger guarantees, and facilities supportive of novices (there will always be more novices than experts).

4/43

Introduction to C++11 and its use inside Qt

Rules of Thumbs From the C++11 FAQ:

Maintain stability and compatibility Prefer libraries to language extensions Prefer generality to specialization Support both experts and novices Increase type safety Improve performance and ability to work directly with hardware Fit into the real world 5/43

Introduction to C++11 and its use inside Qt

Example 1 2 3 4 5 6 7

QString processString ( const QString & str ) { enum State { Ok , Cancel }; QVector < QPair < State , QString > > stack ; stack . append ({ State :: Ok , str }); // ... }

What is specific to C++11 in this code?

6/43

Introduction to C++11 and its use inside Qt

Example 1 2 3 4 5 6 7

QString processString ( const QString & str ) { enum State { Ok , Cancel }; QVector < QPair < State , QString > > stack ; stack . append ({ State :: Ok , str }); // ... }

What is specific to C++11 in this code? use of bracket initilizer

6/43

Introduction to C++11 and its use inside Qt

Example 1 2 3 4 5 6 7

QString processString ( const QString & str ) { enum State { Ok , Cancel }; QVector < QPair < State , QString > > stack ; stack . append ({ State :: Ok , str }); // ... }

What is specific to C++11 in this code? use of bracket initilizer use of >> without a space

6/43

Introduction to C++11 and its use inside Qt

Example 1 2 3 4 5 6 7

QString processString ( const QString & str ) { enum State { Ok , Cancel }; QVector < QPair < State , QString > > stack ; stack . append ({ State :: Ok , str }); // ... }

What is specific to C++11 in this code? use of bracket initilizer use of >> without a space Scoped State::Ok

6/43

Introduction to C++11 and its use inside Qt

Example 1 2 3 4 5 6 7

QString processString ( const QString & str ) { enum State { Ok , Cancel }; QVector < QPair < State , QString > > stack ; stack . append ({ State :: Ok , str }); // ... }

What is specific to C++11 in this code? use of bracket initilizer use of >> without a space Scoped State::Ok use of local type State as template parameter 6/43

Introduction to C++11 and its use inside Qt

New Features

7/43

Introduction to C++11 and its use inside Qt

auto

1 2 3 4 5 6

8/43

QString Obj :: foo ( int blah ) { QHash < int , QString > dict = bar (); auto it = dict . find ( blah ); // ... }

Introduction to C++11 and its use inside Qt

Member Initializers

1 2 3 4 5 6 7

9/43

class X { // ... private : bool m_enabled = false ; int m_state = 0; QByteArray m_name = " None " ; }

Introduction to C++11 and its use inside Qt

Range Based for

1 2 3 4 5 6

10/43

bool Obj :: foo ( const QStringList & list ) { for ( const QString & it : list ) { // ... } }

Introduction to C++11 and its use inside Qt

Uniform Initialisation In C++98 1 2 3

int b (1); // variable definition QVariant c (); // function declaration QVariant d ( QString ()); // oops

4 5 6 7 8

11/43

QPoint p (1 ,2); int i = {2}; // yes , you can do that QString a [] = { " foo " , " bar " }; // ok // QVector < QString > v = { " foo " , " bar " }; // error

Introduction to C++11 and its use inside Qt

Uniform Initialisation In C++11 1 2 3

int b {1}; // variable definition QVariant c {}; // default constructor QVariant d { QString ()}; // Works as expected

4 5 6 7 8

12/43

QPoint p {1 ,2}; int i = {2}; // = is optional QString a [] { " foo " , " bar " }; QVector < QString > v = { " foo " , " bar " }; // works

Introduction to C++11 and its use inside Qt

Uniform Initialisation In C++11 1 2 3 4

struct X x1 = X x2 = X* p =

X { int a , b ; }; X {1 ,2}; {1 ,2}; // the = is optional new X {1 ,2};

5 6 7 8 9 10

13/43

struct D : X { D ( int x , int y , int z ) : X {x , y } , c { z } { /* ... */ }; int c ; };

Introduction to C++11 and its use inside Qt

Uniform Initialisation In C++11 1 2 3 4 5

X foo ( const X & a ) { X b { a }; return {2 ,3}; } foo ({4 ,5});

6 7

X x5 {4.2 , 4.5}

// error : narrowing

8 9 10

14/43

// using initializer_list constructor ( from Qt 4.8) QVector { {1 ,2} , {2 ,4} , {4 ,5} };

Introduction to C++11 and its use inside Qt

initializer_list

1 2 3 4 5 6 7 8 9

15/43

# ifdef Q _ C O M P I L E R _ I N I T I A L I Z E R _ L I S T S template < typename T > QVector :: QVector ( std :: initializer_list args ) { d = Data :: allocate ( args . size ()); copyConstruct ( args . begin () , args . end () , d - > begin ()); d - > size = args . size (); } # endif

Introduction to C++11 and its use inside Qt

C K&R syntax 1 2 3 4 5 6

16/43

int plus (x , y ) int x ; int y ; { return x + y ; }

Introduction to C++11 and its use inside Qt

Lambda

λ 17/43

Introduction to C++11 and its use inside Qt

Lambda

[foo] (int a) -> int { return a + foo; } Capture: Variables that you capture Parametter list: The perametters of the function Return type (optional) Function body

18/43

Introduction to C++11 and its use inside Qt

Lambda [foo] (int a) -> int { return a + foo; } struct { double foo; int operator()(int a) { return a + foo; } }

18/43

Introduction to C++11 and its use inside Qt

Lambda Example

1 2 3 4 5

19/43

QList < int > f ( const QList < int > & list , double foo ) { auto functor = [ foo ]( int a ) { return a + foo ; }; return QtConcurrent :: mapped ( list , functor ); }

Introduction to C++11 and its use inside Qt

Lambda capture 1

int a {1} , b {2} , c {3};

2 3 4

// ’a ’ by value , ’b ’ by reference auto f1 = [a , & b ]() { b = a ; };

5 6 7

// everything by reference auto f2 = [&]() { b = a ; };

8 9 10

// everything by value auto f3 = [=]() { return a + c ; };

11 12 13

20/43

// everything by value , ’b ’ by reference auto f4 = [= ,& b ]() { b = a + c ; };

Introduction to C++11 and its use inside Qt

Lambda Example (Qt5) 1 2 3 4 5 6 7 8 9 10 11 12

21/43

void Doc :: saveDocument () { QFileDialog * dlg = new QFileDialog (); dlg - > open (); QObject :: connect ( dlg , & QDialog :: finished , [ dlg , this ]( int result ) { if ( result ) { QFile file ( dlg - > selectedFiles (). first ()); // ... } dlg - > deleteLater (); }); }

Introduction to C++11 and its use inside Qt

Function Declaration 1 2 3 4 5

struct Foo { enum State { /* ... */ }; /* ... */ State func ( State ); };

6 7 8

22/43

// Error State Foo :: func ( State arg ) { /* ... */ }

Introduction to C++11 and its use inside Qt

Function Declaration 1 2 3 4 5

struct Foo { enum State { /* ... */ }; /* ... */ State func ( State ); };

6 7 8

// Error State Foo :: func ( State arg ) { /* ... */ }

Alternative function syntax 1 2

22/43

auto Foo :: func ( State arg ) -> State { /* ... */ }

Introduction to C++11 and its use inside Qt

decltype

1 2 3 4

template < typename A , typename B > auto dotProduct ( A vect_a , B vect_b ) -> decltype ( vect_a [0]* vect_b [0]) { /* ... */ }

5 6 7 8 9 10

23/43

QList < int > a { /* ... */ }; QVector < float > b { /* ... */ }; auto p = dotProduct (a , b );

Introduction to C++11 and its use inside Qt

Default and Deleted function 1 2 3 4 5 6 7

1 2 3

24/43

struct MyObject { virtual ~ MyObject () = default ; MyObject ( int ); MyObject () = default ; int someFunction ( QObject *); int someFunction ( QWidget *) = delete ; }; # define Q_DISABLE_COPY ( Class ) \ Class ( const Class &) = delete ; \ Class & operator =( const Class &) = delete ;

Introduction to C++11 and its use inside Qt

Q_DECL_DELETE

1 2 3 4 5 6

25/43

struct MyObject { void myFunction ( int ); // ... private : void myFunction ( bool ) Q_DECL_DELETE ; };

Introduction to C++11 and its use inside Qt

Rvalue References 1 2 3 4 5 6 7 8 9 10

struct string { char * data ; string ( const char * str ) : data ( strdup ( str )) {} string ( const string & o ) : data ( strdup ( o . data )) {} ~ string () { free ( data ); } string & operator =( const string & o ) { free ( data ); data = strdup ( o . data ) return * this ; } };

11 12 13 14

26/43

template < class T > swap ( T &a , T & b ) { T tmp ( a ); a = b ; b = tmp ; }

Introduction to C++11 and its use inside Qt

Rvalue References 1 2 3 4 5 6 7 8 9

struct string { /* ... */ string ( const string & o ); // copy constructor string ( string && o ) // move constructor : data ( o . data ) { o . data = 0; } string & operator =( const string & o ); // copy assignme string & operator =( string && o ) // move assignment { swap ( data , o . data ); } };

10 11 12 13 14 15

27/43

template < class T > swap ( T &a , T & b ) { T tmp = std :: move ( a ); a = std :: move ( b ); b = std :: move ( tmp ); } Introduction to C++11 and its use inside Qt

Rvalue References

1 2

X a; X f ();

3 4 5

X & r1 = a ; X & r2 = f ();

// bind r1 to a ( an lvalue ) // error : f () is an rvalue ; can ’t bind

6 7 8 9

28/43

X && rr1 = f (); // ok : bind rr1 to temporary X && rr2 = a // error : bind a is an lvalue X && rr3 = std :: move ( a ) // ok

Introduction to C++11 and its use inside Qt

Move Sementic

1 2 3 4 5 6

# ifdef Q _ C O M P I L E R _ R V A L U E _ R E F S inline QString :: QString ( QString && other ) : d ( other . d ) { other . d = Data :: sharedNull (); }

7 8 9 10

29/43

inline QString :: QString & operator =( QString && other ) { qSwap (d , other . d ); return * this ; } # endif

Introduction to C++11 and its use inside Qt

Perfect Forwarding 1 2 3 4 5 6 7 8 9

template < class T > class QSharedPointer { /* ... */ # if defined ( Q _ C O M P I L E R _ R V A L U E _ R E F S ) \ && defined ( Q _ C O M P I L E R _ V A R I A D I C _ T E M P L A T E S ) template < typename ... Args > static QSharedPointer create ( Args && ... args ) { QSharedPointer result ( Qt :: Uninitialized ); result . d = Private :: create (& result . value );

10 11 12 13 14 15 16

30/43

// now initialize the data new ( result . data ()) T ( std :: forward < Args >( args )...); result .d - > setQObjectShared ( result . value , true ); return result ; } # endif Introduction to C++11 and its use inside Qt

constexpr

1 2 3

switch ( btn ) { case Qt :: LeftButton : /* ... */ break ; case Qt :: RightButton : /* ... */ break ;

4

// error ? the operator | convert to QFlags case Qt :: LeftButton | Qt :: RightButton : /* ... */ break ; default : /* ... */

5 6 7 8 9

31/43

}

Introduction to C++11 and its use inside Qt

constexpr 1 2 3 4 5 6 7

template < typename Enum > class QFlags { int i ; public : constexpr QFlags ( Enum e ) i { e } {} constexpr operator int () { return i ; } // ... };

8 9 10 11 12

32/43

# define Q _ D E C L A R E _ O P E R A T O R S _ F O R _ F L A G S ( ENUM ) \ constexpr inline QFlags < ENUM > operator |( ENUM a , ENUM b ) \ { return QFlags ( ENUM ( a | b )); }

Introduction to C++11 and its use inside Qt

constexpr 1 2 3 4 5 6 7

template < typename Enum > class QFlags { int i ; public : Q_DECL_CONSTEXPR QFlags ( Enum e ) i { e } {} Q_DECL_CONSTEXPR operator int () { return i ; } // ... };

8 9 10 11 12

33/43

# define Q _ D E C L A R E _ O P E R A T O R S _ F O R _ F L A G S ( ENUM ) \ Q_DECL_CONSTEXPR inline QFlags < ENUM > operator | \ ( ENUM a , ENUM b ) \ { return QFlags ( ENUM ( a | b )); }

Introduction to C++11 and its use inside Qt

Explicit Override

1 2 3 4

1 2 3 4

34/43

struct A { virtual void foo ( int ); virtual void bar ( int ) const ; }; struct B : public A { void foo ( float ); // oops void bar ( int ); // oops };

Introduction to C++11 and its use inside Qt

Explicit Override 1 2 3 4

1 2 3 4 5 6

struct A { virtual void foo ( int ); virtual void bar ( int ) const ; }; struct B void void void void };

: public A { foo () override ; // bar ( int ) override ; baz ( int ) override ; foo ( int ) override ;

7 8 9 10

34/43

struct C : public A { void foo ( int ) final ; };

Introduction to C++11 and its use inside Qt

compilation error // compilation error // compilation error // ok

Explicit Override 1 2 3 4

1 2 3 4 5 6

struct A { virtual void foo ( int ); virtual void bar ( int ) const ; }; struct B void void void void };

: public A { foo () Q_DECL_OVERRIDE ; // compilation error bar ( int ) Q_DECL_OVERRIDE ; // compilation error baz ( int ) Q_DECL_OVERRIDE ; // compilation error foo ( int ) Q_DECL_OVERRIDE ; // ok

7 8 9 10

34/43

struct C : public A { void foo ( int ) Q_DECL_FINAL ; };

Introduction to C++11 and its use inside Qt

String Literals Unicode strings 1 2

// utf -8 const char * str1 = u8 " v \ u00e6r s \ u00e5 god " ;

3 4 5

// utf -16 const char16_t * str2 = u " v \ u00e6r s \ u00e5 god " ;

6 7 8

1

// utf -32 const char32_t * str3 = U " v \ u00e6r s \ u00e5 god " ; QStringLiteral ( " Hello " ); (http://woboq.com/blog/qstringliteral.html)

35/43

Introduction to C++11 and its use inside Qt

Raw Literals

C++98 1 2

ret . replace ( QRegExp ( " (\\\\*)\" " ) , " \"\\1\\1\\^\"\" " )

Raw litteral 1 2

36/43

ret . replace ( QRegExp ( R " -( (\\*)" ) -" ) , R "( "\1\1\^"" )" );

Introduction to C++11 and its use inside Qt

enum class

1 2 3

enum Color { Blue , Red , Yellow }; enum class State { Ok , Cancel }; enum class SomeEnum ; // forward declare ( sizeof ( int ))

4 5

enum OtherEnum : char {A , B }; // specify the size

6 7 8 9

37/43

Color color1 = Blue , color2 = Color :: Red ; State state1 = Cancel ; // error State state2 = State :: Cancel ;

Introduction to C++11 and its use inside Qt

... nullptr Generalized POD Generalized unions user defined litteral explicit conversion operators noexcept (Q_DECL_NOTHROW , Q_DECL_NOEXCEPT, Q_DECL_NOEXCEPT_EXPR)

delegating constructors Inline namespace 38/43

Introduction to C++11 and its use inside Qt

Templates Variatic template Default template arguments for function templates SFINAE for expressions Extern templates Local and unnamed types as template arguments Template aliases static_assert (Q_STATIC_ASSERT , Q_STATIC_ASSERT_X) 39/43

Introduction to C++11 and its use inside Qt

Concurrency

Memory model Thread Local Storage (thread_local) Atomic operations futures, mutexes, . . .

40/43

Introduction to C++11 and its use inside Qt

More STL Features unordered_map (QHash) Smart pointers (unique_ptr, shared_ptr, weak_ptr) bind, function more algorithms (min, max, minmax, all_of, any_of, is_sorted, copy_if, copy_n, partition_copy, iota ...) Regular expressions Random number generation ... 41/43

Introduction to C++11 and its use inside Qt

http://abstrusegoose.com/249

42/43

Introduction to C++11 and its use inside Qt

The End CONFIG += c++11

Questions [email protected]

visit http://woboq.com

43/43

Introduction to C++11 and its use inside Qt