SlideShare une entreprise Scribd logo
1  sur  111
Télécharger pour lire hors ligne
Beginning Direct3D Game Programming:
C++11 Primer
jintaeks@gmail.com
Division of Digital Contents, DongSeo University.
March 2016
C++11
 C++11 is a version of the standard for the programming
language C++.
 It was approved by International Organization for
Standardization (ISO) on 12 August 2011,
replacing C++03,[1] and superseded by C++14 on 18 August
2014.[2]
 Although one of the design goals was to prefer changes to
the libraries over changes to the core language,[4] C++11 does
make several additions to the core language.
2
Design goals
 Maintain stability and compatibility with C++98 and possibly
with C.
 Prefer introducing new features via the standard library, rather
than extending the core language.
 Improve C++ to facilitate systems and library design, rather
than introduce new features useful only to specific
applications.
3
Extensions to the C++ core language
 Rvalue references and move constructors.
 Extern template
 Initializer lists
 Uniform initializations
 Type inference
 Ranged-based for loop
 Lambda functions and expressions
 Alternative function syntax
 Explicit override and final
 Null pointer constant
 Explicit conversion operator
 …
4
Rvalue references and move constructors
 rvalues? as they often lie on the right side of an assignment.
 In C++03 and before, temporaries were intended to never be
modifiable and were considered to be indistinguishable from
const T& types.
 C++11 adds a new non-const reference type called an rvalue
reference, identified by T&&.
 This refers to temporaries that are permitted to be modified
after they are initialized, for the purpose of allowing "move
semantics".
5
 If a std::vector<T> temporary is created or returned from a
function, it can be stored only by creating a new
std::vector<T> and copying all the rvalue's data into it.
 If std::vector<T> is a C++03 version without a move
constructor, then the copy constructor will be invoked with
a const std::vector<T>&, incurring a significant memory
allocation.
 Move constructor not only forgoes the expense of a deep
copy, but is safe and invisible.
6
std::move(), perfect forwarding
 For safety reasons, a named variable will never be considered
to be an rvalue even if it is declared as such. To get an rvalue,
the function template std::move() should be used.
 Due to the nature of the wording of rvalue references, and to
some modification to the wording for lvalue references
(regular references), rvalue references allow developers to
provide perfect function forwarding.
7
basic concepts of rvalue
class KTest {
public:
KTest() {
std::cout << "constructorrn";
}
KTest( const KTest& rhs ) {
std::cout << "copy constructorrn";
}
~KTest() {
std::cout << "destructorrn";
}
};
8
KTest F( KTest t ) {
return t;
}
void G( const KTest& t ) {
std::cout << "lvalue ref G " << std::endl;
}
void G( KTest&& t ) {
//KTest u = std::move( t );
//KTest u = t;
std::cout << "rvalue ref G " << std::endl;
}
int main() {
KTest t;
KTest u = t;
u = F( KTest() );
std::cout << "rnbefore call Grn";
G( KTest() );
}
9
constructor
copy constructor
constructor
copy constructor
destructor
destructor
before call G
constructor
lvalue ref G
destructor
destructor
destructor
KTest F( KTest t ) {
return t;
}
void G( const KTest& t ) {
std::cout << "lvalue ref G " << std::endl;
}
void G( KTest&& t ) {
//KTest u = std::move( t );
//KTest u = t;
std::cout << "rvalue ref G " << std::endl;
}
int main() {
KTest t;
KTest u = t;
u = F( KTest() );
std::cout << "rnbefore call Grn";
G( KTest() );
}
10
constructor
copy constructor
constructor
copy constructor
destructor
destructor
before call G
constructor
rvalue ref G
destructor
destructor
destructor
KTest F( KTest t ) {
return t;
}
void G( const KTest& t ) {
std::cout << "lvalue ref G " << std::endl;
}
void G( KTest&& t ) {
KTest u = std::move( t );
//KTest u = t;
std::cout << "rvalue ref G " << std::endl;
}
int main() {
KTest t;
KTest u = t;
u = F( KTest() );
std::cout << "rnbefore call Grn";
G( KTest() );
}
11
We want to call the move
constructor of 'u'.
A named variable will never be
considered to be an rvalue even if it
is declared as such. To get an rvalue,
the function
template std::move() should be used.
move constructor
struct A {
std::string s;
A() : s( "test" ) { std::cout << "constructor An"; }
A( const A& o ) : s( o.s ) { std::cout << "copy constructor An"; }
A( A&& o ) : s( std::move( o.s ) ) { std::cout << "move constructor An"; }
};
A f( A a ) {
return a;
}
struct B : public A {
std::string s2;
int n;
};
B g( B b ) {
return b;
}
12
we expect below things in 'B':
* implicit move constructor B::(B&&)
* calls A's move constructor
* calls s2's move constructor
* and makes a bitwise copy of n
* but in Visual Studio 2013, implicit
functions do not call base class's
corresponding functions.
int main() {
std::cout << "Trying to move An";
A a1 = f( A() ); // move-construct from rvalue temporary
std::cout << "Before move, a1.s = " << a1.s << "n";
A a2 = std::move( a1 ); // move-construct from xvalue
std::cout << "After move, a1.s = " << a1.s << "n";
std::cout << "Trying to move Bn";
B b1 = g( B() );
std::cout << "Before move, b1.s = " << b1.s << "n";
B b2 = std::move( b1 ); // calls implicit move ctor
std::cout << "After move, b1.s = " << b1.s << "n";
}
13
Trying to move A
constructor A
move constructor A
Before move, a1.s = test
move constructor A
After move, a1.s =
Trying to move B
constructor A
copy constructor A
Before move, b1.s = test
copy constructor A
After move, b1.s = test
struct A {
std::string s;
A() : s( "test" ) { std::cout << "constructor An"; }
A( const A& o ) : s( o.s ) { std::cout << "copy constructor An"; }
A( A&& o ) : s( std::move( o.s ) ) { std::cout << "move constructor An"; }
};
struct C : public A {
std::string s2;
int n;
C() : A() { std::cout << "constructor Cn"; }
C( const C& o ) : A( o ) { std::cout << "copy constructor Cn"; }
C( C&& o ) : A( std::move( o ) ) { std::cout << "move constructor Cn"; }
//C( C&& o ) : A( o ) { std::cout << "move constructor Cn"; }
};
14
KTest u = t; differs from u = t;
class KTest {
public:
KTest() {
std::cout << "constructorrn";
}
KTest( const KTest& rhs ) {
std::cout << "copy constructorrn";
}
~KTest() {
std::cout << "destructorrn";
}
KTest& operator=( const KTest& rhs ) {
std::cout << "operator=rn";
return *this;
}
};
int main() {
KTest t;
KTest u = t;
KTest v;
v = t; // this is same as v.operator=(t);
}15
constructor
copy constructor
constructor
operator=
destructor
destructor
destructor
real world example
class MemoryBlock {
public:
explicit MemoryBlock( size_t length )
: _length( length )
, _data( new int[ length ] ) {
std::cout << "In MemoryBlock(size_t). length = " << _length << "." << std::endl;
}
// Destructor.
~MemoryBlock() {
std::cout << "In ~MemoryBlock(). length = " << _length << ".";
if( _data != nullptr ) {
std::cout << " Deleting resource.";
// Delete the resource.
delete[] _data;
_data = nullptr;
}
std::cout << std::endl;
}
16
MemoryBlock( const MemoryBlock& other )
: _length( other._length )
, _data( new int[ other._length ] ) {
std::cout << "In MemoryBlock(const MemoryBlock&). length = "
<< other._length << ". Copying resource." << std::endl;
std::copy( other._data, other._data + _length, _data );
}
MemoryBlock& operator=( const MemoryBlock& other ) {
std::cout << "In operator=(const MemoryBlock&). length = "
<< other._length << ". Copying resource." << std::endl;
if( this != &other ) {
delete[] _data;
_length = other._length;
_data = new int[ _length ];
std::copy( other._data, other._data + _length, _data );
}
return *this;
}17
// Move constructor.
MemoryBlock( MemoryBlock&& other )
: _data( nullptr )
, _length( 0 ) {
std::cout << "In MemoryBlock(MemoryBlock&&). length = "
<< other._length << ". Moving resource." << std::endl;
// Copy the data pointer and its length from the
// source object.
_data = other._data;
_length = other._length;
// Release the data pointer from the source object so that
// the destructor does not free the memory multiple times.
other._data = nullptr;
other._length = 0;
}
18
// Move assignment operator.
MemoryBlock& operator=( MemoryBlock&& other ) {
std::cout << "In operator=(MemoryBlock&&). length = "
<< other._length << "." << std::endl;
if( this != &other ) {
// Free the existing resource.
delete[] _data;
// Copy the data pointer and its length from the
// source object.
_data = other._data;
_length = other._length;
// Release the data pointer from the source object so that
// the destructor does not free the memory multiple times.
other._data = nullptr;
other._length = 0;
}
return *this;
}
19
Modification to the definition of plain old data
 In C++03, a class or struct must follow a number of rules for
it to be considered a plain old data(POD) type.
 Types that fit this definition produce object layouts that are
compatible with C, and they could also be initialized statically.
 if someone were to create a C++03 POD type and add a non-
virtual member function, this type would no longer be a POD
type.
 C++11 relaxed several of the POD rules, by dividing the POD
concept into two separate concepts:trivial and standard-
layout.
20
A class with complex move and copy constructors
may not be trivial, but it could be standard-
layout and thus interop with C.
trivial
 it is legal to copy data around via memcpy, rather than having
to use a copy constructor.
① Has a trivial default constructor. This may use the default
constructor syntax(SomeConstructor() = default;).
② Has trivial copy and move constructors, which may use the
default syntax.
③ Has trivial copy and move assignment operators, which may
use the default syntax.
④ Has a trivial destructor, which must not be virtual.
21
standard-layout
 It orders and packs its members in a way that is compatible
with C.
① It has no virtual functions
② It has no virtual base classes
③ All its non-static data members have the same access control
(public, private, protected)
④ All its non-static data members, including any in its base
classes, are in the same one class in the hierarchy
⑤ The above rules also apply to all the base classes and to all
non-static data members in the class hierarchy
⑥ It has no base classes of the same type as the first defined
non-static data member
22
#include <type_traits>
struct X {
// It means that you want to use the compiler-generated version
// of that function, so you don't need to specify a body.
X() = default;
};
struct Y {
Y() {};
};
int main() {
static_assert( std::is_trivial<X>::value, "X should be trivial" );
static_assert( std::is_pod<X>::value, "X should be POD" );
static_assert( !std::is_trivial<Y>::value, "Y should not be trivial" );
static_assert( !std::is_pod<Y>::value, "Y should not be POD" );
}
23
Extern template
 In C++03, the compiler must instantiate a template whenever
a fully specified template is encountered in a translation unit.
 If the template is instantiated with the same types in many
translation units, this can dramatically increase compile
times.
 C++11 now provides this syntax:
extern template class std::vector<MyClass>;
24
Initializer lists
 C++03 inherited the initializer-list feature from C. A struct or
array is given a list of arguments in braces, in the order of the
members' definitions in the struct.
struct Object {
float first;
int second;
};
Object scalar = {0.43f, 10}; //One Object, with first=0.43f and second=10
Object anArray[] = {{13.4f, 3}, {43.28f, 29}, {5.934f, 17}}; //An array of three
Objects
25
 C++03 allows initializer-lists only on structs and classes that
conform to the Plain Old Data (POD) definition.
 C++11 extends initializer-lists, so they can be used for all
classes including standard containers like std::vector.
class SequenceClass {
public:
SequenceClass(std::initializer_list<int> list);
};
SequenceClass some_var = {1, 4, 5, 6};
 This constructor is a special kind of constructor, called an
initializer-list-constructor. Classes with such a constructor are
treated specially during uniform initialization.
26
first-class citizen
 In programming language design, a first-class
citizen (also type, object, entity, or value) in a given
programming language is an entity which supports all the
operations generally available to other entities.
 The simplest scalar data types, such as integer and floating-
point numbers, are nearly always first-class.
 In C++, arrays is not first-class: they cannot be assigned as
objects or passed as parameters to a subroutine.
 For example, C++ doesn't supports array assignment, and
when they are passed as parameters, only the position of their
first element is actually passed—their size is lost.
27
 The class std::initializer_list<> is a first-class C++11 standard
library type.
 However, they can be initially constructed statically by the
C++11 compiler only via use of the {} syntax.
void function_name(std::initializer_list<float> list);
function_name({1.0f, -3.45f, -0.4f});
 Standard containers can also be initialized in these ways:
std::vector<std::string> v = { "xyzzy", "plugh", "abracadabra" };
std::vector<std::string> v({ "xyzzy", "plugh", "abracadabra" });
std::vector<std::string> v{ "xyzzy", "plugh", "abracadabra" };
28
My own initializer_list?
29
The initializer_list is a real
type, it can be used in other
places besides class
constructors. Regular
functions can take typed
initializer lists as arguments.
But! std::initializer_list is
treated specially. So you can
not create your own
initializer_list.
Uniform initialization
 C++03 has a number of problems with initializing types.
Several ways to do this exist, and some produce different
results when interchanged.
 For example, The traditional constructor syntax can look like a
function declaration.
 Only aggregates and POD types can be initialized with
aggregate initializers (using SomeType var = {/*stuff*/};).
30
 C++11 provides a syntax that allows for fully uniform type
initialization that works on any object.
struct BasicStruct {
int x;
double y;
};
struct AltStruct {
AltStruct(int x, double y) : x_{x}, y_{y} {}
private:
int x_;
double y_;
};
BasicStruct var1{5, 3.2};
AltStruct var2{2, 4.3};
31
struct IdString {
std::string name;
int identifier;
};
IdString get_string() {
return {"foo", 42}; //Note the lack of explicit
type.
}
 The following code will call the initializer list constructor, not
the constructor of std::vector that takes a single size
parameter and creates the vector with that size.
std::vector<int> the_vec{4};
32
Type inference: decltype
 In C++03 (and C), to use a variable, its type must be specified
explicitly.
 However, with the advent of template types and template
metaprogramming techniques, the type of something,
particularly the well-defined return value of a function, may
not be easily expressed.
33
well-defined
 In mathematics, an expression is called well-defined if its
definition assigns it a unique interpretation or value.
Otherwise, the expression is said to be not well-defined .
 A function is well-defined if it gives the same result when the
representation of the input is changed without changing the
value of the input.
 For instance if f takes real numbers as input, and if f(0.5) does
not equal f(1/2) then f is not well-defined.
34
 C++11 allows this to be mitigated in two ways. First, the
definition of a variable with an explicit initialization can use
the auto keyword.
auto some_strange_callable_type = std::bind(&some_function, _2,
_1, some_object);
auto other_variable = 5;
for (std::vector<int>::const_iterator itr = myvec.cbegin(); itr !=
myvec.cend(); ++itr)
for (auto itr = myvec.cbegin(); itr != myvec.cend(); ++itr)
 Further, the keyword decltype can be used to determine the
type of expression at compile-time.
int some_int;
decltype(some_int) other_integer_variable = 5;
35
when to use
// will not compiled!
template<typename T, typename U>
decltype(T+U) add( T t, U u )
{
return t + u;
}
template<typename T, typename U>
auto add2( T t, U u ) -> decltype( t + u ) // return type depends on template parameters
{
return t + u;
}
36
template<typename T, typename U>
auto add2( T t, U u ) -> decltype( t + u ) // return
type depends on template parameters
{
return t + u;
}
int main() {
printf( "%i %irn", i, j );
auto f = []( int a, int b ) -> int {
return a * b;
};
decltype( f ) g = f; // the type of a lambda
function is unique and unnamed
i = f( 2, 2 );
j = g( 3, 3 );
printf( "%i %irn", i, j );
std::cout << add2( 2, 3 ) << std::endl;
}
37
3 6
4 9
5
Alternative function syntax
 In C++03 this is disallowed.
template<class Lhs, class Rhs>
Ret adding_func(const Lhs &lhs, const Rhs &rhs) {return
lhs + rhs;} //Ret must be the type of lhs+rhs
 Even with the aforementioned C++11 functionality
of decltype, this is not possible:
template<class Lhs, class Rhs>
decltype(lhs+rhs) adding_func(const Lhs &lhs, const Rhs
&rhs) {return lhs + rhs;} //Not legal C++11
38
trailing-return-type
 To work around this, C++11 introduced a new function
declaration syntax, with a trailing-return-type:
template<class Lhs, class Rhs>
auto adding_func(const Lhs &lhs, const Rhs &rhs) ->
decltype(lhs+rhs) {return lhs + rhs;}
 This syntax can be used for more mundane function
declarations and definitions.
struct SomeStruct {
auto func_name(int x, int y) -> int;
};
auto SomeStruct::func_name(int x, int y) -> int {
return x + y;
}
39
Range-based for loop
 C++11 extends the syntax of the for statement to allow for
easy iteration over a range of elements.
int my_array[5] = {1, 2, 3, 4, 5};
// double the value of each element in my_array:
for (int &x : my_array) {
x *= 2;
}
// similar but also using type inference for array elements
for (auto &x : my_array) {
x *= 2;
}
 It will work for C-style arrays, initializer lists, and any type that
has begin() and end() functions defined for it that return iterators.
40
my own container can be used in range-based for loop
template<class T>
class MyVector {
public:
typedef T* iterator;
public:
T m_data[ 100 ];
int m_begin;
int m_end;
MyVector();
T& operator[]( int i ) { return m_data[ i ]; }
void push_back( T& d );
T* begin();
T* end();
};//class MyVector
41
class CData {
int data;
public:
CData( int d = 0 ) : data(d) {}
void DoIt() { printf( "data=%dn", data ); }//DoIt()
};//class CTest
template<class T>
MyVector<T>::MyVector() {
m_begin = 0;
m_end = 0;
}
template<class T>
void MyVector<T>::push_back( T& d ) {
m_data[ m_end++ ] = d;
}
template<class T>
T* MyVector<T>::begin() {
return &m_data[ m_begin ];
}
template<class T>
T* MyVector<T>::end() {
return &m_data[ m_end ];
}
42
void main() {
CData d1( 1 ), d2( 2 ), d3( 3 );
MyVector<CData> vec;
vec.push_back( d1 );
vec.push_back( d2 );
vec.push_back( d3 );
vec[ 1 ].DoIt();
for( CData& d : vec ) {
d.DoIt();
}
}//main()
Lambda functions and expressions
 C++11 provides the ability to create anonymous functions,
called lambda functions. These are defined as follows:
[](int x, int y) -> int { return x + y; }
 The return type of lambda can be omitted as long as
all return expressions return the same type. A lambda can
optionally be a closure.
43
when to use
int CompFunc( int left_, int right_ ) {
return left_ < right_;
}
class KCompare {
public:
int operator()( int left_, int right_ ) const {
return left_ < right_;
}
};
template<typename T>
void CompareTest( int a, int b, T predicate_ ) {
//const bool bCompResult = predicate_.operator()(a, b);
const bool bCompResult = predicate_( a, b );
printf( "CompareTest result = %drn", bCompResult );
}
int main() {
CompareTest( 2, 3, CompFunc );
CompareTest( 2, 3, KCompare() );
}
44
template<typename T>
void CompareTest( int a, int b, T predicate_ ) {
//const bool bCompResult = predicate_.operator()(a, b);
const bool bCompResult = predicate_( a, b );
printf( "CompareTest result = %drn", bCompResult );
}
int main() {
auto compareLambda = []( int a, int b )->int {return a < b; };
CompareTest( 2, 3, compareLambda );
CompareTest( 2, 3, []( int a, int b )->int {return a < b; } );
}
45
capture list
[capture](parameters) -> return_type { function_body }
[] //no variables defined. Attempting to use any external
variables in the lambda is an error.
[x, &y] //x is captured by value, y is captured by reference
[&] //any external variable is implicitly captured by reference if
used
[=] //any external variable is implicitly captured by value if used
[&, x] //x is explicitly captured by value. Other variables will be
captured by reference
[=, &z] //z is explicitly captured by reference. Other variables will
be captured by value
46
int main() {
std::vector<int> some_list{ 1, 2, 3, 4, 5 };
int total = 0;
std::for_each( begin( some_list ), end( some_list ), [&total]( int x ) { total += x; } );
printf( "%irn", total );
}
47
class KTest {
public:
int some_func() const { return 2; }
void Test() {
std::vector<int> some_list{ 1, 2, 3, 4, 5 };
int total = 0;
int value = 5;
std::for_each( begin( some_list ), end( some_list ), [&, value, this]( int x ) {
total += x * value * this->some_func();
} );
}
};
 This will cause total to be stored as a reference, but value will
be stored as a copy.
 The capture of this is special. It can only be captured by
value, not by reference. this can only be captured if the
closest enclosing function is a non-static member function.
 A lambda expression with an empty capture specification ([])
can be implicitly converted into a function pointer with the
same type as the lambda was declared with.
auto a_lambda_func = [](int x) { /*...*/ };
void (* func_ptr)(int) = a_lambda_func;
func_ptr(4); //calls the lambda.
48
various usage of lambda
std::function<double( double )> f0 = []( double x ) {return 1; };
auto f1 = []( double x ) {return x; };
decltype( f0 ) fa[ 3 ] = { f0, f1, []( double x ) {return x*x; } };
std::vector<decltype( f0 )> fv = { f0, f1 };
fv.push_back( []( double x ) {return x*x; } );
for( int i = 0; i<fv.size(); i++ )
std::cout << fv[ i ]( 2.0 ) << std::endl;
for( int i = 0; i<3; i++ )
std::cout << fa[ i ]( 2.0 ) << std::endl;
for( auto &f : fv )
std::cout << f( 2.0 ) << std::endl;
for( auto &f : fa )
std::cout << f( 2.0 ) << std::endl;
std::cout << eval( f0 ) << std::endl;
std::cout << eval( f1 ) << std::endl;
std::cout << eval( []( double x ) {return x*x; } ) << std::endl;
49
Object construction improvement
 In C++03, constructors of a class are not allowed to call other
constructors of that class.
 C++11 allows constructors to call other peer constructors
(termed delegation).
class SomeType {
int number;
public:
SomeType(int new_number) : number(new_number) {}
SomeType() : SomeType(42) {}
};
50
 For member initialization, C++11 allows this syntax:
class SomeClass {
public:
SomeClass() {}
explicit SomeClass(int new_value) : value(new_value) {}
private:
int value = 5;
};
51
Explicit overrides and final
 In C++03, it is possible to accidentally create a new virtual
function, when one intended to override a base class function.
struct Base {
virtual void some_func(float);
};
struct Derived : Base {
virtual void some_func(int);
};
 Because it has a different signature, it creates a second virtual
function.
struct Base {
virtual void some_func(float);
};
struct Derived : Base {
virtual void some_func(int) override; // ill-formed - doesn't override a base
class method
};
52
 C++11 also adds the ability to prevent inheriting from classes
or simply preventing overriding methods in derived classes.
This is done with the special identifier final.
struct Base1 final { };
struct Derived1 : Base1 { }; // ill-formed because the class Base1 has been marked
final
struct Base2 {
virtual void f() final;
};
struct Derived2 : Base2 {
void f(); // ill-formed because the virtual function Base2::f has been marked final
};
53
Null pointer constant
 Since the dawn of C in 1972, the constant 0 has had the
double role of constant integer and null pointer constant.
 The ambiguity inherent in the double meaning of 0 was dealt
with in C by using the preprocessor macro NULL, which
commonly expands to either ((void*)0) or 0.
void foo(char *);
void foo(int);
 If NULL is defined as 0, the statement foo(NULL); will call
foo(int), which is almost certainly not what the programmer
intended.
 C++11 corrects this by introducing a new keyword to serve as
a distinguished null pointer constant: nullptr. It is of
type nullptr_t, which is implicitly convertible and comparable
to any pointer type or pointer-to-member type.
54
class KPointer {
public:
template<typename T>
KPointer& operator=( T rhs ) = delete;
KPointer& operator=( char* rhs ) {
m_pData = rhs;
return *this;
}
// do not use like this. it's just example.
KPointer& operator=( nullptr_t rhs ) {
delete m_pData;
m_pData = nullptr;
return *this;
}
public:
char* m_pData;
};
55
int main() {
KPointer t;
t = new char;
//t = 0; // compile time error!
t = nullptr;
return 0;
}
Strongly typed enumerations
 In C++03, enumerations are not type-safe.
 They are effectively integers, even when the enumeration
types are distinct.
 This allows the comparison between two enum values of
different enumeration types.
 The underlying integral type is implementation-defined.
 C++11 allows a special classification of enumeration that has
none of these issues. This is expressed using the enum class.
56
enum class Enumeration {
Val1,
Val2,
Val3 = 100,
Val4 // = 101
};
 This enumeration is type-safe. Enum class values are not
implicitly converted to integers. Thus, they cannot be
compared to integers either.
 The underlying type of enum classes is always known. The
default type is int; this can be overridden to a different
integral type.
enum class Enum2 : unsigned int {Val1, Val2};
57
Right angle bracket
 C++03's parser defines “>>” as the right shift operator in all
cases.
 C++11 improves the specification of the parser so that
multiple right angle brackets will be interpreted as closing the
template argument list where it is reasonable.
template<bool Test> class SomeType;
std::vector<SomeType<1>2>> x1; /* Interpreted as a std::vector of
SomeType<true>, followed by "2 >> x1", which is not legal syntax for a
declarator. 1 is true. */
58
Explicit conversion operators
 C++98 added the explicit keyword as a modifier on
constructors to prevent single-argument constructors from
being used as implicit type conversion operators.
 However, this does nothing for actual conversion operators.
 For example, a smart pointer class may have an operator
bool() to allow it to act more like a primitive pointer: if it
includes this conversion, it can be tested with if
(smart_ptr_variable) (which would be true if the pointer
was non-null and false otherwise).
 However, this allows other, unintended conversions as well.
 (We will look into more detail later in this presentation).
59
Template aliases
 In C++03, it is not possible to create a typedef template.
template <typename First, typename Second, int Third>
class SomeType;
template <typename Second>
typedef SomeType<OtherType, Second, 5> TypedefName; // Illegal in C++03
 C++11 adds this ability with this syntax.
template <typename First, typename Second, int Third>
class SomeType;
template <typename Second>
using TypedefName = SomeType<OtherType, Second, 5>;
 The using syntax can be also used as type aliasing in C++11:
typedef void (*FunctionType)(double); // Old style
using FunctionType = void (*)(double); // New introduced syntax
60
Variadic templates
 C++11 allows template definitions to take an arbitrary
number of arguments of any type.
template<typename... Values> class tuple;
 The above template class tuple can be used like this:
tuple<int, std::vector<int>, std::map<<std::string>,
std::vector<int>>> some_instance_name;
61
ellipsis operator (…)
Probably the most famous function in both C & C++ to take advantage of this mechanism is
printf-function in C standard library:
int printf (const char* format, ... );
Ellipsis mechanism can also be used with preprocessor in a form of a macro. A macro taking
a variable number of parameters is called a variadic macro.
#define VARIADIC_MACRO(...)
In C++, this ellipsis operator got a new meaning in different context called exception
handling. The operator is used in catch blocks after try blocks:
try{
// Try block.
}
catch(...){
// Catch block.
}
62
now ellipsis (…) can be used in C++11 template
 The ellipsis (...) operator has two roles:
– When it occurs to the left of the name of a parameter, it declares a
parameter pack.
– Using the parameter pack, the user can bind zero or more arguments
to the variadic template parameters.
– When the ellipsis operator occurs to the right of a template or
function call argument, it unpacks the parameter packs into separate
arguments.
 Another operator used with variadic templates is the sizeof...-
operator. sizeof... operator can be used to determine the
amount of types given into a variadic template.
template<typename... Arguments>
class VariadicTemplate{
private:
static const unsigned short int size = sizeof...(Arguments); };
63
simple example: variadic function template
template<typename T>
T adder( T v ) {
return v;
}
template<typename T, typename... Args>
T adder( T first, Args... args ) {
return first + adder( args... );
}
void main() {
long sum = adder( 1, 2, 3, 8, 7 );
printf( "%irn", sum );
std::string s1 = "x", s2 = "aa", s3 = "bb", s4 = "yy";
std::string ssum = adder( s1, s2, s3, s4 );
printf( "%srn", ssum.c_str() );
}
64
variadic template version of printf()
void printf2( const char *s ) {
while( *s ) {
if( *s == '%' ) {
if( *( s + 1 ) == '%' ) {
++s;
} else {
throw std::runtime_error( "invalid format string: missing arguments" );
}
}
std::cout << *s++;
}
}
65
template<typename T, typename... Args>
void printf2( const char *s, T value, Args... args ) {
while( *s ) {
if( *s == '%' ) {
if( *( s + 1 ) == '%' ) {
++s;
} else {
std::cout << value;
s += 2; // this only works on 2 characters format strings ( %d, %f, etc ). Fails
miserably with %5.4f
printf2( s, args... ); // call even when *s == 0 to detect extra arguments
return;
}
}
std::cout << *s++;
}
}
66
variadic class template
template<bool B, class T, class F>
struct conditional { typedef T type; };
template<class T, class F>
struct conditional<false, T, F> { typedef F type; };
template <typename... Args>
struct find_biggest;
// the biggest of one thing is that one thing
template <typename First>
struct find_biggest<First> {
typedef First type;
};
template <typename First, typename... Args>
struct find_biggest<First, Args...> {
typedef typename conditional<
sizeof( First ) >= sizeof( typename find_biggest<Args...>::type )
, First, typename find_biggest<Args...>::type>::type type;
};
67
// the biggest of everything in Args and First
template <typename First, typename... Args>
struct find_biggest<First, Args...> {
static const int size = sizeof...( Args ) + 1;
typedef typename find_biggest<Args...>::type next;
typedef typename conditional< sizeof( First ) >= sizeof(next)
, First, next>::type type;
};
void main() {
find_biggest<char, long long, float, short>::type i;
printf( "%irn", sizeof( i ) ); // 8
printf( "%i %irn", sizeof( i ) // 5
, find_biggest<char, long long, float, short>::size );
}
68
New string literals
 It is also sometimes useful to avoid escaping strings manually,
particularly for using literals of XMLfiles, scripting languages,
or regular expressions.
 C++11 provides a raw string literal:
#include <stdio.h>
void main() {
char* p0 = R"(The String Data  Stuff " rn)";
char* p1 = R"delimiter(The String Data  Stuff " rn)delimiter";
printf( "%srn", p0 );
printf( "%srn", p1 );
}
69
Thread-local storage
 In addition to the existing static, dynamic and automatic.
 A new thread-local storage duration is indicated by the
storage specifier thread_local.
 Microsoft Visual Studio 2013 doesn't support thread_local,
instead you can use __declspec(thread).
70
we want to maintain g_pData for each thread. How?
#include <iostream>
#include <thread>
#include <windows.h>
int* g_pData = nullptr;
void foo( int i ) {
if( g_pData == nullptr ) {
g_pData = new int[ 11 ];
printf( "g_pData allocated %irn", i );
}
Sleep( 500 );
printf( "%irn", i );
if( g_pData != nullptr ) {
delete[] g_pData;
printf( "g_pData destroyed %irn", i );
}
}
71
int main() {
std::thread first( foo, 1 );
std::thread second( foo, 3 );
std::cout << "main, foo and foo now
execute concurrently...n";
// synchronize threads:
first.join(); // pauses until first finishes
second.join(); // pauses until second finishes
std::cout << "foo and bar completed.n";
return 0;
}
 If you want to maintain the single g_pData, you must add
thread safety features.
72
__declspec(thread) int* g_pData = nullptr;
void foo( int i ) {
if( g_pData == nullptr ) {
g_pData = new int[ 11 ];
printf( "g_pData allocated %irn", i );
}
Sleep( 500 );
printf( "%irn", i );
if( g_pData != nullptr ) {
delete[] g_pData;
printf( "g_pData destroyed %irn", i );
}
}
int main() {
std::thread first( foo, 1 );
std::thread second( foo, 3 );
std::cout << "main, foo and foo now execute concurrently...n";
73
// synchronize threads:
first.join(); // pauses until first finishes
second.join(); // pauses until second finishes
std::cout << "foo and bar completed.n";
return 0;
}
g_pData allocated 1
g_pData allocated 3
main, foo and foo now execute
concurrently...
1
g_pData destroyed 1
3
g_pData destroyed 3
foo and bar completed.
Explicitly defaulted and deleted special member function
 For classes that do not provide them for themselves:
 In C++03, the compiler provides, a default constructor, a copy
constructor, a copy assignment operator (operator=), and a
destructor. The programmer can override these defaults by
defining custom versions.
 C++11 allows the explicit defaulting and deleting of these
special member functions.
 The = delete specifier can be used to prohibit calling any
function, which can be used to disallow calling a member
function with particular parameters.
74
famous usage
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
class KData {
public:
KData( const KData& rhs ) = delete;
KData& operator=( const KData& rhs ) = delete;
KData( int i ) : m_iData{ i } {}
public:
int m_iData = 0;
};
int main() {
std::vector<KData> v;
v.push_back( { 1 } ); // will not be compiled!
return 0;
}
75
Type long long int
 This resulted in long int having size of 64 bits on some
popular implementations and 32 bits on others.
 C++11 adds a new integer type long long int to address this
issue. It is guaranteed to be at least as large as a long int, and
have no fewer than 64 bits.
76
Static assertions
 The new utility introduces a new way to test assertions at
compile-time, using the new keyword static_assert.
template<class T>
struct Check {
static_assert(sizeof(int) <= sizeof(T), "T is not big enough!");
};
77
C++ standard library changes
 Threading facilities
 General-purpose smart pointers
 Wrapper reference
 Type traits for metaprogramming
78
Allow garbage collected implementations
 When someday, garbage collector added into the C++ library.
We need to tell to the garbage collector about that do not
delete 'p' pointer it will be reachable later in my code.
 To tell this, we need to call std::declare_reachable(p);.
 In previous example, if we do not call
std::declare_reachable(p);, the pointer 'p' to dynamic object
can be destroyed by the garbage collector due to there is no
live pointer to dynamic object by 'scrambling p' statement.
 To prevent this situation, we must tell to the garbage collector
about reachableness of pointer to dynamic object.
 std::declare_reachable() is used for this purpose.
79
int main() {
int * p = new int( 1 ); // dynamic object
std::declare_reachable( p );
p = (int*)( ( std::uintptr_t )p ^ UINTPTR_MAX ); // scrambling p
// dynamic object not reachable by any live safely-derived pointer
p = std::undeclare_reachable( (int*)( ( std::uintptr_t )p ^ UINTPTR_MAX ) );
// p is back again a safely-derived pointer to the dynamic object
std::cout << "p: " << *p << 'n';
delete p;
return 0;
}
80
General-purpose smart pointers
 std::shared_ptr
 std::weak_ptr
 std::unique_ptr
81
void 참조를 특화로 구현
82
template<class T> struct shared_ptr_traits
{
typedef T& reference;
};
template<> struct shared_ptr_traits<void>
{
typedef void reference;
};  void타입에 대한 reference가 가능하도록
템플릿 특화specialization을 사용하여 미리
구현해 둡니다.
 기타 type-trait에 대한 설명은 생략합니다.
shared_ptr: 생성자 구현
83
template<class T> class shared_ptr
{
public:
typedef shared_ptr<T> this_type;
typedef T value_type;
typedef T* pointer;
typedef typename shared_ptr_traits<T>::reference reference;
public:
shared_ptr(T * p = 0) : px(p), pn(0)
{
if( px != NULL )
pn = new int(1);
}
 생성자에서는 전달받은 raw pointer를
초기화합니다.
 참조 카운팅을 위한 메모리 할당을 하고,
참조 카운터를 1로 초기화합니다.
shared_ptr: 복사 생성자와 파괴자 구현
84
shared_ptr( const shared_ptr& right_ ) : px( 0 ), pn( 0 )
{
release();
px = right_.px;
pn = right_.pn;
if( px != NULL )
*pn += 1;
}
~shared_ptr()
{
release();
}
 복사 생성자는 먼저 이전에 할당되어 있는
리소스를 해제 합니다.
 새로운 리소스에 대한 참조를 설정하고,
참조 카운터를 증가시킵니다.
shared_ptr: operator=(), operator pointer()
85
shared_ptr& operator=( const shared_ptr& right_ )
{
release();
px = right_.px;
pn = right_.pn;
if( px != NULL )
*pn += 1;
return *this;
}
operator pointer() const
{
return px;
}
 대입 연산자는 복사 생성자와 거의 동일하게
구현합니다.
 타입에 대한 포인터 연산이 제대로
동작하도록 operator T*()를 정의합니다.
shared_ptr: release() 구현
86
void release()
{
if( px != NULL && *pn >= 1 )
{
*pn -= 1;
if( *pn == 0 )
{
delete px;
px = NULL;
delete pn;
pn = NULL;
}//if
}//if
px = NULL;
pn = NULL;
}
 release()는 먼저 참조 카운터를 감소합니다.
 참조 카운터가 0이되면, 실제 리소스를 해제
합니다.
shared_ptr: reset(), use_count() 구현
87
void reset()
{
release();
}
void reset(T * p)
{
release();
px = p;
pn = NULL;
if( px != NULL )
pn = new int(1);
}
int use_count() const { return *pn; }
 reset()은 해제 후 할당과 동일합니다.
 완성된 shared_ptr은 암시적 생성implicit
construction을 지원하지 않으므로,
reset()구현이 반드시 필요합니다.
 use_count()는 현재 참조 카운터를
리턴합니다.
shared_ptr: operator*(), operator->() 구현
88
reference operator*() const // never throws
{
return *px;
}
T* operator->() const // never throws
{
return px;
}
private:
T* px;
int* pn;
};//template<class T> class shared_ptr
 간접지정 연산자와 화살표 연산자가 제대로
동작하도록 함수를 작성합니다.
 void*에 대한 참조가 동작하도록 하기
위해서는 void에 대한 참조를 템플릿 특화로
미리 구현해 두어야 합니다.
main()에서 테스트
89
int main()
{
typedef shared_ptr<int> IntPtr;
IntPtr spInt = new int(3); // spInt.use_count() == 1
if( spInt != NULL )
{
std::cout << *spInt << std::endl; // 3
}//if
IntPtr spInt2 = spInt; // spInt.use_count() == 2
IntPtr spInt3 = spInt; // spInt.use_count() == 3
spInt.reset( new int(4) ); // spInt.use_count() == 1
*spInt = 5; // 3 changed to 5
if( spInt2 != NULL ) // spInt2.use_count() == 2
{
std::cout << *spInt2 << std::endl; // 3
}//if
return 0;
}//int main()
copy-and-swap: swap() 메서드 구현
90
void swap( shared_ptr<T>& right_ ) // never throws
{
std::swap( px, right_.px );
std::swap( pn, right_.pn );
}
 exception safety
1) Basic: component의 invariant는 보존되고, resource
leak은 발생하지 않아야 합니다.
2) Strong: 성공적으로 완료되었던지 예외를 던졌던지 둘
중의 하나여야 합니다.
3) No-throw: 예외를 던지지 않아야 합니다.
 copy-and-swap을 지원하기 위해서 shared_ptr의
swap()은 예외를 던지지 않도록 구현해야 합니다.
shared_ptr: swap()을 반영한 수정
91
shared_ptr& operator=( const shared_ptr& right_ )
{
//release();
//px = right_.px;
//pn = right_.pn;
//if( px != NULL )
// *pn += 1;
this_type(right_).swap(*this);
return *this;
}
void reset(T * p)
{
//release();
//px = p;
//pn = NULL;
//if( px != NULL )
// pn = new int(1);
this_type(p).swap(*this);
}
관찰: if의 조건문 표현식
92
class KBoolTest
{
public:
operator bool() const { return true; }
operator int() const { return 1; }
operator int*() const { return NULL; }
int GetValue() const { return 9; }
};
int main()
{
KBoolTest t;
if( t )
std::cout << t.GetValue() << std::endl;
return 0;
}//int main()
 if문의 조건은 일반적인 bool 표현식이 아닌 C가
허용하는 참인 조건식을 적을 수 있습니다.
 평가의 partial order의 순서는 bool  native
type  pointer의 순입니다.
safe bool idiom
93
//int* p = spInt; // (1)
//if( spInt < spInt ) // (2)
//{
//}  지금까지의 구현은 (1)과 (2)처럼 잘못된
사용이나, 의미없는 bool 표현식을 막지
못합니다.
template <typename T> void some_func(const T& t) {
if (t)
t->print();
}
 smart pointer T에 대해 이 문장이
동작하려면 T는 bool형에 대한 형 변환
연산자를 제공해야 합니다.
해결시도1: operator bool() 구현
94
class Testable {
bool ok_;
public:
explicit Testable(bool b=true):ok_(b) {}
operator bool() const {
return ok_;
}
};  shared_ptr은 자신이 valid한 raw pointer를 가질 때, true를
리턴하는 operator bool()을 작성할 수 있습니다.
operator bool() cont.
95
test << 1; // (1)
int i=test; // (2)
Testable a;
AnotherTestable b;
if (a==b) { // (3)
}
if (a<b) { // (4)
}
 이 구현은 (1), (2) 같은 의미 없는
문장이나, (3), (4) 같은 의미 없는 bool
검사를 막지 못합니다.
해결시도2: operator void*()구현
96
operator void*() const {
return ok_==true ? this : 0;
}
 이 구현은 영리해 보이지만, 아래의 문장처럼
delete를 직접호출 할 수 있는 약점을 가집니다.
Testable test;
delete test;
해결시도3: nested class
97
class Testable {
bool ok_;
public:
explicit Testable(bool b=true):ok_(b) {}
class nested_class;
operator const nested_class*() const {
return ok_ ? reinterpret_cast<const nested_class*>(this) : 0;
}
};
Testable b1,b2;
if (b1==b2) {
}
if (b1<b2) {
}
 safe bool을 위한 nested class 구현 역시 의미없는 bool
검사를 막지 못합니다.
 이 문제를 해결하려면 포인터 형변환이 되지만, < 같은 비교
연산자를 지원하지 않는 데이터 타입을 사용하는 것입니다.
 흥미롭게도 멤버 함수에 대한 포인터가 그렇게 동작합니다!
최종 버전: safe bool idiom
98
class Testable {
bool ok_;
typedef void (Testable::*bool_type)() const;
void this_type_does_not_support_comparisons() const {}
public:
explicit Testable(bool b=true):ok_(b) {}
operator bool_type() const {
return ok_==true ?
&Testable::this_type_does_not_support_comparisons : 0;
}
};
 if-문장의 조건 표현식에 포인터가 사용될 수 있는
점을 이용하여, 함수 포인터를 리턴하는 연산자
함수를 정의합니다.
shared_ptr의 내부: unspecified_bool_type 사용
99
//operator pointer() const
//{
// return px;
//}
void unspecified_bool() const
{
}
typedef void (shared_ptr::*unspecified_bool_type)() const;
operator unspecified_bool_type() const // never throws
{
return px == 0 ? 0 : &shared_ptr::unspecified_bool;
}
 boost의 실제 코드는
unspecified_bool_type()을 사용합니다.
 C++ 표준 라이브러리 뿐만 아니라, 게임
엔진의 스마트 포인터 구현은 모두 이러한
기법을 사용합니다.
shared_ptr에 적용된 safe bool idiom
100
typedef shared_ptr<int> IntPtr;
IntPtr spInt = new int(3);
IntPtr spInt2 = spInt;
IntPtr spInt3 = spInt;
spInt.reset( new int(4) );
*spInt = 5;
if( spInt2 != NULL )
{
std::cout << *spInt << std::endl;
}//if
int* p = spInt; // (1) error
if( spInt2 < spInt3 ) // (2) error
{
}
 이제 (1)과 (2)같은 의미 없는
문장은 컴파일 시간 에러가
발생합니다.
implicit constructor문제 해결하기
101
void Test( shared_ptr<int> spInt_ )
{
}
int iData = 5;
Test( &iData );
 실제 포인터가 아닌, 포인터 표현식에 대한 shared_ptr
생성을 막을 필요가 있습니다.
 이 문제에 대한 해결방법은 명시적 생성만 가능하도록
클래스를 설계하는 것입니다.
explicit shared_ptr(T * p = 0) : px(p), pn(0)
{
if( px != NULL )
pn = new int(1);
}
Wrapper reference
 A wrapper reference is obtained from an instance of the
template class reference_wrapper.
 Wrapper references are similar to normal references (‘&’) of
the C++ language. To obtain a wrapper reference from any
object the function template std::ref is used.
102
#include <iostream>
// This function will obtain a reference to the parameter 'r' and increment it.
void func( int &r ) { r++; }
// Template function.
template<class F, class P> void g( F f, P t ) { f( t ); }
int main() {
int i = 0;
g( func, i ); // 'g<void (int &r), int>' is instantiated
// then 'i' will not be modified.
std::cout << i << std::endl; // Output -> 0
g( func, std::ref( i ) ); // 'g<void(int &r),reference_wrapper<int>>' is instantiated
// then 'i' will be modified.
std::cout << i << std::endl; // Output -> 1
}
103
Polymorphic wrappers for function objects
 Polymorphic wrappers for function objects are similar
to function pointers in semantics and syntax, but are less
tightly bound and can refer to anything which can be called
(function pointers, member function pointers, or functors)
whose arguments are compatible with those of the wrapper.
 The template class function was defined inside the
header <functional>, without needing any change to the C++
language.
104
#include <functional>
#include <iostream>
struct Foo {
Foo( int num ) : num_( num ) {}
void print_add( int i ) { std::cout << num_ + i << 'n'; }
int num_;
};
void print_num( int i ) {
std::cout << i << 'n';
}
struct PrintNum {
void operator()( int i ) const {
std::cout << i << 'n';
}
};
105
int main() {
// store a free function
std::function<void( int )> f_display = print_num;
f_display( -9 );
// store a lambda
std::function<void()> f_display_42 = []() { print_num( 42 ); };
f_display_42();
// store a call to a member function
using namespace std::placeholders;
const Foo foo( 314159 );
std::function<void( int )> f_add_display = std::bind( &Foo::print_add, foo, _1 );
f_add_display( 1 );
// store a call to a function object
std::function<void( int )> f_display_obj = PrintNum();
f_display_obj( 18 );
}
106
Type traits for metaprogramming
 Metaprogramming consists of creating a program that creates
or modifies another program (or itself). This can happen
during compilation or during execution.
107
template<int B, int N>
struct Pow {
// recursive call and recombination.
enum{ value = B*Pow<B, N-1>::value };
};
template< int B >
struct Pow<B, 0> {
// ''N == 0'' condition of termination.
enum{ value = 1 };
};
int quartic_of_three = Pow<3, 4>::value;
108
type traits
 Many algorithms can operate on different types of data;
C++'s templates support generic programming and make
code more compact and useful.
 Nevertheless it is common for algorithms to need information
on the data types being used. This information can be
extracted during instantiation of a template class using type
traits.
 Type traits can identify the category of an object and all the
characteristics of a class.
 They are defined in the new header <type_traits>.
109
// First way of operating.
template< bool B > struct Algorithm {
template<class T> static int do_it( T& a ) {
printf( "firstrn" );
return 0;
}
};
// Second way of operating.
template<> struct Algorithm<true> {
template<class T> static int do_it( T a ) {
printf( "secondrn" );
return 0;
}
};
110
// Instantiating 'elaborate' will automatically
// instantiate the correct way to operate.
template<class T>
int elaborate( T a ) {
return Algorithm<std::is_floating_point<T>::value>::do_it( a );
}
void main() {
elaborate( 1.0f ); // second
elaborate( 1 ); // first
}
References
 https://en.wikipedia.org/wiki/C++11
 http://eli.thegreenplace.net/2014/variadic-templates-in-c/
111

Contenu connexe

Tendances

HexRaysCodeXplorer: make object-oriented RE easier
HexRaysCodeXplorer: make object-oriented RE easierHexRaysCodeXplorer: make object-oriented RE easier
HexRaysCodeXplorer: make object-oriented RE easierAlex Matrosov
 
HDTR images with Photoshop Javascript Scripting
HDTR images with Photoshop Javascript ScriptingHDTR images with Photoshop Javascript Scripting
HDTR images with Photoshop Javascript ScriptingDavid Gómez García
 
The Ring programming language version 1.5.1 book - Part 7 of 180
The Ring programming language version 1.5.1 book - Part 7 of 180The Ring programming language version 1.5.1 book - Part 7 of 180
The Ring programming language version 1.5.1 book - Part 7 of 180Mahmoud Samir Fayed
 
iOS Development with Blocks
iOS Development with BlocksiOS Development with Blocks
iOS Development with BlocksJeff Kelley
 
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTRT3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTRDavid Gómez García
 
Box2D with SIMD in JavaScript
Box2D with SIMD in JavaScriptBox2D with SIMD in JavaScript
Box2D with SIMD in JavaScriptIntel® Software
 
05 - Qt External Interaction and Graphics
05 - Qt External Interaction and Graphics05 - Qt External Interaction and Graphics
05 - Qt External Interaction and GraphicsAndreas Jakl
 
Using QString effectively
Using QString effectivelyUsing QString effectively
Using QString effectivelyRoman Okolovich
 
[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)croquiscom
 
Story of static code analyzer development
Story of static code analyzer developmentStory of static code analyzer development
Story of static code analyzer developmentAndrey Karpov
 
The Ring programming language version 1.5.3 book - Part 92 of 184
The Ring programming language version 1.5.3 book - Part 92 of 184The Ring programming language version 1.5.3 book - Part 92 of 184
The Ring programming language version 1.5.3 book - Part 92 of 184Mahmoud Samir Fayed
 
[C++ gui programming with qt4] chap9
[C++ gui programming with qt4] chap9[C++ gui programming with qt4] chap9
[C++ gui programming with qt4] chap9Shih-Hsiang Lin
 
Racing To Win: Using Race Conditions to Build Correct and Concurrent Software
Racing To Win: Using Race Conditions to Build Correct and Concurrent SoftwareRacing To Win: Using Race Conditions to Build Correct and Concurrent Software
Racing To Win: Using Race Conditions to Build Correct and Concurrent SoftwareFastly
 
The Ring programming language version 1.9 book - Part 43 of 210
The Ring programming language version 1.9 book - Part 43 of 210The Ring programming language version 1.9 book - Part 43 of 210
The Ring programming language version 1.9 book - Part 43 of 210Mahmoud Samir Fayed
 
03 - Qt UI Development
03 - Qt UI Development03 - Qt UI Development
03 - Qt UI DevelopmentAndreas Jakl
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJSKyung Yeol Kim
 

Tendances (20)

HexRaysCodeXplorer: make object-oriented RE easier
HexRaysCodeXplorer: make object-oriented RE easierHexRaysCodeXplorer: make object-oriented RE easier
HexRaysCodeXplorer: make object-oriented RE easier
 
HDTR images with Photoshop Javascript Scripting
HDTR images with Photoshop Javascript ScriptingHDTR images with Photoshop Javascript Scripting
HDTR images with Photoshop Javascript Scripting
 
The Ring programming language version 1.5.1 book - Part 7 of 180
The Ring programming language version 1.5.1 book - Part 7 of 180The Ring programming language version 1.5.1 book - Part 7 of 180
The Ring programming language version 1.5.1 book - Part 7 of 180
 
iOS Development with Blocks
iOS Development with BlocksiOS Development with Blocks
iOS Development with Blocks
 
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTRT3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
T3chFest2016 - Uso del API JavaScript de Photoshop para obtener fotos HDTR
 
Return of c++
Return of c++Return of c++
Return of c++
 
OpenVG 1.1 Reference Card
OpenVG 1.1 Reference Card OpenVG 1.1 Reference Card
OpenVG 1.1 Reference Card
 
Box2D with SIMD in JavaScript
Box2D with SIMD in JavaScriptBox2D with SIMD in JavaScript
Box2D with SIMD in JavaScript
 
05 - Qt External Interaction and Graphics
05 - Qt External Interaction and Graphics05 - Qt External Interaction and Graphics
05 - Qt External Interaction and Graphics
 
Using QString effectively
Using QString effectivelyUsing QString effectively
Using QString effectively
 
[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)
 
Qt Widget In-Depth
Qt Widget In-DepthQt Widget In-Depth
Qt Widget In-Depth
 
Story of static code analyzer development
Story of static code analyzer developmentStory of static code analyzer development
Story of static code analyzer development
 
The Ring programming language version 1.5.3 book - Part 92 of 184
The Ring programming language version 1.5.3 book - Part 92 of 184The Ring programming language version 1.5.3 book - Part 92 of 184
The Ring programming language version 1.5.3 book - Part 92 of 184
 
Day 1
Day 1Day 1
Day 1
 
[C++ gui programming with qt4] chap9
[C++ gui programming with qt4] chap9[C++ gui programming with qt4] chap9
[C++ gui programming with qt4] chap9
 
Racing To Win: Using Race Conditions to Build Correct and Concurrent Software
Racing To Win: Using Race Conditions to Build Correct and Concurrent SoftwareRacing To Win: Using Race Conditions to Build Correct and Concurrent Software
Racing To Win: Using Race Conditions to Build Correct and Concurrent Software
 
The Ring programming language version 1.9 book - Part 43 of 210
The Ring programming language version 1.9 book - Part 43 of 210The Ring programming language version 1.9 book - Part 43 of 210
The Ring programming language version 1.9 book - Part 43 of 210
 
03 - Qt UI Development
03 - Qt UI Development03 - Qt UI Development
03 - Qt UI Development
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJS
 

En vedette

Beginning direct3d gameprogrammingmath02_logarithm_20160324_jintaeks
Beginning direct3d gameprogrammingmath02_logarithm_20160324_jintaeksBeginning direct3d gameprogrammingmath02_logarithm_20160324_jintaeks
Beginning direct3d gameprogrammingmath02_logarithm_20160324_jintaeksJinTaek Seo
 
Beginning direct3d gameprogramming01_thehistoryofdirect3dgraphics_20160407_ji...
Beginning direct3d gameprogramming01_thehistoryofdirect3dgraphics_20160407_ji...Beginning direct3d gameprogramming01_thehistoryofdirect3dgraphics_20160407_ji...
Beginning direct3d gameprogramming01_thehistoryofdirect3dgraphics_20160407_ji...JinTaek Seo
 
Beginning direct3d gameprogramming01_20161102_jintaeks
Beginning direct3d gameprogramming01_20161102_jintaeksBeginning direct3d gameprogramming01_20161102_jintaeks
Beginning direct3d gameprogramming01_20161102_jintaeksJinTaek Seo
 
Beginning direct3d gameprogrammingmath05_matrices_20160515_jintaeks
Beginning direct3d gameprogrammingmath05_matrices_20160515_jintaeksBeginning direct3d gameprogrammingmath05_matrices_20160515_jintaeks
Beginning direct3d gameprogrammingmath05_matrices_20160515_jintaeksJinTaek Seo
 
Beginning direct3d gameprogramming06_firststepstoanimation_20161115_jintaeks
Beginning direct3d gameprogramming06_firststepstoanimation_20161115_jintaeksBeginning direct3d gameprogramming06_firststepstoanimation_20161115_jintaeks
Beginning direct3d gameprogramming06_firststepstoanimation_20161115_jintaeksJinTaek Seo
 
Beginning direct3d gameprogrammingmath06_transformations_20161019_jintaeks
Beginning direct3d gameprogrammingmath06_transformations_20161019_jintaeksBeginning direct3d gameprogrammingmath06_transformations_20161019_jintaeks
Beginning direct3d gameprogrammingmath06_transformations_20161019_jintaeksJinTaek Seo
 
Beginning direct3d gameprogramming03_programmingconventions_20160414_jintaeks
Beginning direct3d gameprogramming03_programmingconventions_20160414_jintaeksBeginning direct3d gameprogramming03_programmingconventions_20160414_jintaeks
Beginning direct3d gameprogramming03_programmingconventions_20160414_jintaeksJinTaek Seo
 
Beginning direct3d gameprogramming02_overviewofhalandcom_20160408_jintaeks
Beginning direct3d gameprogramming02_overviewofhalandcom_20160408_jintaeksBeginning direct3d gameprogramming02_overviewofhalandcom_20160408_jintaeks
Beginning direct3d gameprogramming02_overviewofhalandcom_20160408_jintaeksJinTaek Seo
 
Beginning direct3d gameprogrammingmath03_vectors_20160328_jintaeks
Beginning direct3d gameprogrammingmath03_vectors_20160328_jintaeksBeginning direct3d gameprogrammingmath03_vectors_20160328_jintaeks
Beginning direct3d gameprogrammingmath03_vectors_20160328_jintaeksJinTaek Seo
 
Beginning direct3d gameprogramming04_3dfundamentals_20160414_jintaeks
Beginning direct3d gameprogramming04_3dfundamentals_20160414_jintaeksBeginning direct3d gameprogramming04_3dfundamentals_20160414_jintaeks
Beginning direct3d gameprogramming04_3dfundamentals_20160414_jintaeksJinTaek Seo
 
Beginning direct3d gameprogrammingmath04_calculus_20160324_jintaeks
Beginning direct3d gameprogrammingmath04_calculus_20160324_jintaeksBeginning direct3d gameprogrammingmath04_calculus_20160324_jintaeks
Beginning direct3d gameprogrammingmath04_calculus_20160324_jintaeksJinTaek Seo
 
Beginning direct3d gameprogramming05_thebasics_20160421_jintaeks
Beginning direct3d gameprogramming05_thebasics_20160421_jintaeksBeginning direct3d gameprogramming05_thebasics_20160421_jintaeks
Beginning direct3d gameprogramming05_thebasics_20160421_jintaeksJinTaek Seo
 
Beginning direct3d gameprogramming08_usingtextures_20160428_jintaeks
Beginning direct3d gameprogramming08_usingtextures_20160428_jintaeksBeginning direct3d gameprogramming08_usingtextures_20160428_jintaeks
Beginning direct3d gameprogramming08_usingtextures_20160428_jintaeksJinTaek Seo
 
Beginning direct3d gameprogramming07_lightsandmaterials_20161117_jintaeks
Beginning direct3d gameprogramming07_lightsandmaterials_20161117_jintaeksBeginning direct3d gameprogramming07_lightsandmaterials_20161117_jintaeks
Beginning direct3d gameprogramming07_lightsandmaterials_20161117_jintaeksJinTaek Seo
 
Beginning direct3d gameprogramming10_shaderdetail_20160506_jintaeks
Beginning direct3d gameprogramming10_shaderdetail_20160506_jintaeksBeginning direct3d gameprogramming10_shaderdetail_20160506_jintaeks
Beginning direct3d gameprogramming10_shaderdetail_20160506_jintaeksJinTaek Seo
 
Beginning direct3d gameprogramming09_shaderprogramming_20160505_jintaeks
Beginning direct3d gameprogramming09_shaderprogramming_20160505_jintaeksBeginning direct3d gameprogramming09_shaderprogramming_20160505_jintaeks
Beginning direct3d gameprogramming09_shaderprogramming_20160505_jintaeksJinTaek Seo
 
Logarithm Problems
Logarithm ProblemsLogarithm Problems
Logarithm ProblemsReversearp
 
Power Point Project
Power Point ProjectPower Point Project
Power Point ProjectHaganl
 
65 properties of logarithm
65 properties of logarithm65 properties of logarithm
65 properties of logarithmmath126
 

En vedette (20)

Beginning direct3d gameprogrammingmath02_logarithm_20160324_jintaeks
Beginning direct3d gameprogrammingmath02_logarithm_20160324_jintaeksBeginning direct3d gameprogrammingmath02_logarithm_20160324_jintaeks
Beginning direct3d gameprogrammingmath02_logarithm_20160324_jintaeks
 
Beginning direct3d gameprogramming01_thehistoryofdirect3dgraphics_20160407_ji...
Beginning direct3d gameprogramming01_thehistoryofdirect3dgraphics_20160407_ji...Beginning direct3d gameprogramming01_thehistoryofdirect3dgraphics_20160407_ji...
Beginning direct3d gameprogramming01_thehistoryofdirect3dgraphics_20160407_ji...
 
Beginning direct3d gameprogramming01_20161102_jintaeks
Beginning direct3d gameprogramming01_20161102_jintaeksBeginning direct3d gameprogramming01_20161102_jintaeks
Beginning direct3d gameprogramming01_20161102_jintaeks
 
Beginning direct3d gameprogrammingmath05_matrices_20160515_jintaeks
Beginning direct3d gameprogrammingmath05_matrices_20160515_jintaeksBeginning direct3d gameprogrammingmath05_matrices_20160515_jintaeks
Beginning direct3d gameprogrammingmath05_matrices_20160515_jintaeks
 
Beginning direct3d gameprogramming06_firststepstoanimation_20161115_jintaeks
Beginning direct3d gameprogramming06_firststepstoanimation_20161115_jintaeksBeginning direct3d gameprogramming06_firststepstoanimation_20161115_jintaeks
Beginning direct3d gameprogramming06_firststepstoanimation_20161115_jintaeks
 
Beginning direct3d gameprogrammingmath06_transformations_20161019_jintaeks
Beginning direct3d gameprogrammingmath06_transformations_20161019_jintaeksBeginning direct3d gameprogrammingmath06_transformations_20161019_jintaeks
Beginning direct3d gameprogrammingmath06_transformations_20161019_jintaeks
 
Beginning direct3d gameprogramming03_programmingconventions_20160414_jintaeks
Beginning direct3d gameprogramming03_programmingconventions_20160414_jintaeksBeginning direct3d gameprogramming03_programmingconventions_20160414_jintaeks
Beginning direct3d gameprogramming03_programmingconventions_20160414_jintaeks
 
Beginning direct3d gameprogramming02_overviewofhalandcom_20160408_jintaeks
Beginning direct3d gameprogramming02_overviewofhalandcom_20160408_jintaeksBeginning direct3d gameprogramming02_overviewofhalandcom_20160408_jintaeks
Beginning direct3d gameprogramming02_overviewofhalandcom_20160408_jintaeks
 
Beginning direct3d gameprogrammingmath03_vectors_20160328_jintaeks
Beginning direct3d gameprogrammingmath03_vectors_20160328_jintaeksBeginning direct3d gameprogrammingmath03_vectors_20160328_jintaeks
Beginning direct3d gameprogrammingmath03_vectors_20160328_jintaeks
 
Beginning direct3d gameprogramming04_3dfundamentals_20160414_jintaeks
Beginning direct3d gameprogramming04_3dfundamentals_20160414_jintaeksBeginning direct3d gameprogramming04_3dfundamentals_20160414_jintaeks
Beginning direct3d gameprogramming04_3dfundamentals_20160414_jintaeks
 
Beginning direct3d gameprogrammingmath04_calculus_20160324_jintaeks
Beginning direct3d gameprogrammingmath04_calculus_20160324_jintaeksBeginning direct3d gameprogrammingmath04_calculus_20160324_jintaeks
Beginning direct3d gameprogrammingmath04_calculus_20160324_jintaeks
 
Beginning direct3d gameprogramming05_thebasics_20160421_jintaeks
Beginning direct3d gameprogramming05_thebasics_20160421_jintaeksBeginning direct3d gameprogramming05_thebasics_20160421_jintaeks
Beginning direct3d gameprogramming05_thebasics_20160421_jintaeks
 
Beginning direct3d gameprogramming08_usingtextures_20160428_jintaeks
Beginning direct3d gameprogramming08_usingtextures_20160428_jintaeksBeginning direct3d gameprogramming08_usingtextures_20160428_jintaeks
Beginning direct3d gameprogramming08_usingtextures_20160428_jintaeks
 
Beginning direct3d gameprogramming07_lightsandmaterials_20161117_jintaeks
Beginning direct3d gameprogramming07_lightsandmaterials_20161117_jintaeksBeginning direct3d gameprogramming07_lightsandmaterials_20161117_jintaeks
Beginning direct3d gameprogramming07_lightsandmaterials_20161117_jintaeks
 
Beginning direct3d gameprogramming10_shaderdetail_20160506_jintaeks
Beginning direct3d gameprogramming10_shaderdetail_20160506_jintaeksBeginning direct3d gameprogramming10_shaderdetail_20160506_jintaeks
Beginning direct3d gameprogramming10_shaderdetail_20160506_jintaeks
 
Beginning direct3d gameprogramming09_shaderprogramming_20160505_jintaeks
Beginning direct3d gameprogramming09_shaderprogramming_20160505_jintaeksBeginning direct3d gameprogramming09_shaderprogramming_20160505_jintaeks
Beginning direct3d gameprogramming09_shaderprogramming_20160505_jintaeks
 
Logarithm Problems
Logarithm ProblemsLogarithm Problems
Logarithm Problems
 
Power Point Project
Power Point ProjectPower Point Project
Power Point Project
 
Logarithm
 Logarithm Logarithm
Logarithm
 
65 properties of logarithm
65 properties of logarithm65 properties of logarithm
65 properties of logarithm
 

Similaire à Direct3D Game Programming C++11 Primer

data Structure Lecture 1
data Structure Lecture 1data Structure Lecture 1
data Structure Lecture 1Teksify
 
C++totural file
C++totural fileC++totural file
C++totural filehalaisumit
 
Constructors and Destructors
Constructors and DestructorsConstructors and Destructors
Constructors and DestructorsKeyur Vadodariya
 
C++11: Feel the New Language
C++11: Feel the New LanguageC++11: Feel the New Language
C++11: Feel the New Languagemspline
 
Virtual Function and Polymorphism.ppt
Virtual Function and Polymorphism.pptVirtual Function and Polymorphism.ppt
Virtual Function and Polymorphism.pptishan743441
 
Lecture 3, c++(complete reference,herbet sheidt)chapter-13
Lecture 3, c++(complete reference,herbet sheidt)chapter-13Lecture 3, c++(complete reference,herbet sheidt)chapter-13
Lecture 3, c++(complete reference,herbet sheidt)chapter-13Abu Saleh
 
Lecture 9_Classes.pptx
Lecture 9_Classes.pptxLecture 9_Classes.pptx
Lecture 9_Classes.pptxNelyJay
 
pyjamas22_ generic composite in python.pdf
pyjamas22_ generic composite in python.pdfpyjamas22_ generic composite in python.pdf
pyjamas22_ generic composite in python.pdfAsher Sterkin
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and BeyondComicSansMS
 
Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)Geeks Anonymes
 
cppt-170218053903 (1).pptx
cppt-170218053903 (1).pptxcppt-170218053903 (1).pptx
cppt-170218053903 (1).pptxWatchDog13
 

Similaire à Direct3D Game Programming C++11 Primer (20)

Oops lecture 1
Oops lecture 1Oops lecture 1
Oops lecture 1
 
Oops presentation
Oops presentationOops presentation
Oops presentation
 
data Structure Lecture 1
data Structure Lecture 1data Structure Lecture 1
data Structure Lecture 1
 
C++ tutorial
C++ tutorialC++ tutorial
C++ tutorial
 
C++totural file
C++totural fileC++totural file
C++totural file
 
C++ references
C++ referencesC++ references
C++ references
 
Sqlapi0.1
Sqlapi0.1Sqlapi0.1
Sqlapi0.1
 
Constructors and Destructors
Constructors and DestructorsConstructors and Destructors
Constructors and Destructors
 
C++ Programming
C++ ProgrammingC++ Programming
C++ Programming
 
C++ Programming
C++ ProgrammingC++ Programming
C++ Programming
 
C++11: Feel the New Language
C++11: Feel the New LanguageC++11: Feel the New Language
C++11: Feel the New Language
 
Virtual Function and Polymorphism.ppt
Virtual Function and Polymorphism.pptVirtual Function and Polymorphism.ppt
Virtual Function and Polymorphism.ppt
 
Lecture 3, c++(complete reference,herbet sheidt)chapter-13
Lecture 3, c++(complete reference,herbet sheidt)chapter-13Lecture 3, c++(complete reference,herbet sheidt)chapter-13
Lecture 3, c++(complete reference,herbet sheidt)chapter-13
 
Lecture 9_Classes.pptx
Lecture 9_Classes.pptxLecture 9_Classes.pptx
Lecture 9_Classes.pptx
 
pyjamas22_ generic composite in python.pdf
pyjamas22_ generic composite in python.pdfpyjamas22_ generic composite in python.pdf
pyjamas22_ generic composite in python.pdf
 
Cpp tutorial
Cpp tutorialCpp tutorial
Cpp tutorial
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and Beyond
 
Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)
 
cppt-170218053903 (1).pptx
cppt-170218053903 (1).pptxcppt-170218053903 (1).pptx
cppt-170218053903 (1).pptx
 
Qt for beginners
Qt for beginnersQt for beginners
Qt for beginners
 

Plus de JinTaek Seo

Neural network 20161210_jintaekseo
Neural network 20161210_jintaekseoNeural network 20161210_jintaekseo
Neural network 20161210_jintaekseoJinTaek Seo
 
05 heap 20161110_jintaeks
05 heap 20161110_jintaeks05 heap 20161110_jintaeks
05 heap 20161110_jintaeksJinTaek Seo
 
02 linked list_20160217_jintaekseo
02 linked list_20160217_jintaekseo02 linked list_20160217_jintaekseo
02 linked list_20160217_jintaekseoJinTaek Seo
 
Hermite spline english_20161201_jintaeks
Hermite spline english_20161201_jintaeksHermite spline english_20161201_jintaeks
Hermite spline english_20161201_jintaeksJinTaek Seo
 
01 stack 20160908_jintaek_seo
01 stack 20160908_jintaek_seo01 stack 20160908_jintaek_seo
01 stack 20160908_jintaek_seoJinTaek Seo
 
03 fsm how_toimplementai_state_20161006_jintaeks
03 fsm how_toimplementai_state_20161006_jintaeks03 fsm how_toimplementai_state_20161006_jintaeks
03 fsm how_toimplementai_state_20161006_jintaeksJinTaek Seo
 
Beginning direct3d gameprogrammingmath01_primer_20160324_jintaeks
Beginning direct3d gameprogrammingmath01_primer_20160324_jintaeksBeginning direct3d gameprogrammingmath01_primer_20160324_jintaeks
Beginning direct3d gameprogrammingmath01_primer_20160324_jintaeksJinTaek Seo
 
Boost pp 20091102_서진택
Boost pp 20091102_서진택Boost pp 20091102_서진택
Boost pp 20091102_서진택JinTaek Seo
 
아직도가야할길 훈련 20090722_서진택
아직도가야할길 훈련 20090722_서진택아직도가야할길 훈련 20090722_서진택
아직도가야할길 훈련 20090722_서진택JinTaek Seo
 
3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택JinTaek Seo
 
Multithread programming 20151206_서진택
Multithread programming 20151206_서진택Multithread programming 20151206_서진택
Multithread programming 20151206_서진택JinTaek Seo
 
03동물 로봇그리고사람 public_20151125_서진택
03동물 로봇그리고사람 public_20151125_서진택03동물 로봇그리고사람 public_20151125_서진택
03동물 로봇그리고사람 public_20151125_서진택JinTaek Seo
 
20150605 홀트입양예비부모모임 서진택
20150605 홀트입양예비부모모임 서진택20150605 홀트입양예비부모모임 서진택
20150605 홀트입양예비부모모임 서진택JinTaek Seo
 
Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택JinTaek Seo
 

Plus de JinTaek Seo (14)

Neural network 20161210_jintaekseo
Neural network 20161210_jintaekseoNeural network 20161210_jintaekseo
Neural network 20161210_jintaekseo
 
05 heap 20161110_jintaeks
05 heap 20161110_jintaeks05 heap 20161110_jintaeks
05 heap 20161110_jintaeks
 
02 linked list_20160217_jintaekseo
02 linked list_20160217_jintaekseo02 linked list_20160217_jintaekseo
02 linked list_20160217_jintaekseo
 
Hermite spline english_20161201_jintaeks
Hermite spline english_20161201_jintaeksHermite spline english_20161201_jintaeks
Hermite spline english_20161201_jintaeks
 
01 stack 20160908_jintaek_seo
01 stack 20160908_jintaek_seo01 stack 20160908_jintaek_seo
01 stack 20160908_jintaek_seo
 
03 fsm how_toimplementai_state_20161006_jintaeks
03 fsm how_toimplementai_state_20161006_jintaeks03 fsm how_toimplementai_state_20161006_jintaeks
03 fsm how_toimplementai_state_20161006_jintaeks
 
Beginning direct3d gameprogrammingmath01_primer_20160324_jintaeks
Beginning direct3d gameprogrammingmath01_primer_20160324_jintaeksBeginning direct3d gameprogrammingmath01_primer_20160324_jintaeks
Beginning direct3d gameprogrammingmath01_primer_20160324_jintaeks
 
Boost pp 20091102_서진택
Boost pp 20091102_서진택Boost pp 20091102_서진택
Boost pp 20091102_서진택
 
아직도가야할길 훈련 20090722_서진택
아직도가야할길 훈련 20090722_서진택아직도가야할길 훈련 20090722_서진택
아직도가야할길 훈련 20090722_서진택
 
3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택
 
Multithread programming 20151206_서진택
Multithread programming 20151206_서진택Multithread programming 20151206_서진택
Multithread programming 20151206_서진택
 
03동물 로봇그리고사람 public_20151125_서진택
03동물 로봇그리고사람 public_20151125_서진택03동물 로봇그리고사람 public_20151125_서진택
03동물 로봇그리고사람 public_20151125_서진택
 
20150605 홀트입양예비부모모임 서진택
20150605 홀트입양예비부모모임 서진택20150605 홀트입양예비부모모임 서진택
20150605 홀트입양예비부모모임 서진택
 
Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택
 

Dernier

Theory of Machine Notes / Lecture Material .pdf
Theory of Machine Notes / Lecture Material .pdfTheory of Machine Notes / Lecture Material .pdf
Theory of Machine Notes / Lecture Material .pdfShreyas Pandit
 
10 AsymmetricKey Cryptography students.pptx
10 AsymmetricKey Cryptography students.pptx10 AsymmetricKey Cryptography students.pptx
10 AsymmetricKey Cryptography students.pptxAdityaGoogle
 
Novel 3D-Printed Soft Linear and Bending Actuators
Novel 3D-Printed Soft Linear and Bending ActuatorsNovel 3D-Printed Soft Linear and Bending Actuators
Novel 3D-Printed Soft Linear and Bending ActuatorsResearcher Researcher
 
The Satellite applications in telecommunication
The Satellite applications in telecommunicationThe Satellite applications in telecommunication
The Satellite applications in telecommunicationnovrain7111
 
22CYT12 & Chemistry for Computer Systems_Unit-II-Corrosion & its Control Meth...
22CYT12 & Chemistry for Computer Systems_Unit-II-Corrosion & its Control Meth...22CYT12 & Chemistry for Computer Systems_Unit-II-Corrosion & its Control Meth...
22CYT12 & Chemistry for Computer Systems_Unit-II-Corrosion & its Control Meth...KrishnaveniKrishnara1
 
TEST CASE GENERATION GENERATION BLOCK BOX APPROACH
TEST CASE GENERATION GENERATION BLOCK BOX APPROACHTEST CASE GENERATION GENERATION BLOCK BOX APPROACH
TEST CASE GENERATION GENERATION BLOCK BOX APPROACHSneha Padhiar
 
Gravity concentration_MI20612MI_________
Gravity concentration_MI20612MI_________Gravity concentration_MI20612MI_________
Gravity concentration_MI20612MI_________Romil Mishra
 
Secure Key Crypto - Tech Paper JET Tech Labs
Secure Key Crypto - Tech Paper JET Tech LabsSecure Key Crypto - Tech Paper JET Tech Labs
Secure Key Crypto - Tech Paper JET Tech Labsamber724300
 
Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...
Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...
Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...IJAEMSJORNAL
 
70 POWER PLANT IAE V2500 technical training
70 POWER PLANT IAE V2500 technical training70 POWER PLANT IAE V2500 technical training
70 POWER PLANT IAE V2500 technical trainingGladiatorsKasper
 
Machine Learning 5G Federated Learning.pdf
Machine Learning 5G Federated Learning.pdfMachine Learning 5G Federated Learning.pdf
Machine Learning 5G Federated Learning.pdfadeyimikaipaye
 
ADM100 Running Book for sap basis domain study
ADM100 Running Book for sap basis domain studyADM100 Running Book for sap basis domain study
ADM100 Running Book for sap basis domain studydhruvamdhruvil123
 
Robotics Group 10 (Control Schemes) cse.pdf
Robotics Group 10  (Control Schemes) cse.pdfRobotics Group 10  (Control Schemes) cse.pdf
Robotics Group 10 (Control Schemes) cse.pdfsahilsajad201
 
1- Practice occupational health and safety procedures.pptx
1- Practice occupational health and safety procedures.pptx1- Practice occupational health and safety procedures.pptx
1- Practice occupational health and safety procedures.pptxMel Paras
 
Uk-NO1 kala jadu karne wale ka contact number kala jadu karne wale baba kala ...
Uk-NO1 kala jadu karne wale ka contact number kala jadu karne wale baba kala ...Uk-NO1 kala jadu karne wale ka contact number kala jadu karne wale baba kala ...
Uk-NO1 kala jadu karne wale ka contact number kala jadu karne wale baba kala ...Amil baba
 
Uk-NO1 Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Exp...
Uk-NO1 Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Exp...Uk-NO1 Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Exp...
Uk-NO1 Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Exp...Amil baba
 
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.elesangwon
 
Indian Tradition, Culture & Societies.pdf
Indian Tradition, Culture & Societies.pdfIndian Tradition, Culture & Societies.pdf
Indian Tradition, Culture & Societies.pdfalokitpathak01
 

Dernier (20)

Theory of Machine Notes / Lecture Material .pdf
Theory of Machine Notes / Lecture Material .pdfTheory of Machine Notes / Lecture Material .pdf
Theory of Machine Notes / Lecture Material .pdf
 
10 AsymmetricKey Cryptography students.pptx
10 AsymmetricKey Cryptography students.pptx10 AsymmetricKey Cryptography students.pptx
10 AsymmetricKey Cryptography students.pptx
 
Novel 3D-Printed Soft Linear and Bending Actuators
Novel 3D-Printed Soft Linear and Bending ActuatorsNovel 3D-Printed Soft Linear and Bending Actuators
Novel 3D-Printed Soft Linear and Bending Actuators
 
The Satellite applications in telecommunication
The Satellite applications in telecommunicationThe Satellite applications in telecommunication
The Satellite applications in telecommunication
 
22CYT12 & Chemistry for Computer Systems_Unit-II-Corrosion & its Control Meth...
22CYT12 & Chemistry for Computer Systems_Unit-II-Corrosion & its Control Meth...22CYT12 & Chemistry for Computer Systems_Unit-II-Corrosion & its Control Meth...
22CYT12 & Chemistry for Computer Systems_Unit-II-Corrosion & its Control Meth...
 
TEST CASE GENERATION GENERATION BLOCK BOX APPROACH
TEST CASE GENERATION GENERATION BLOCK BOX APPROACHTEST CASE GENERATION GENERATION BLOCK BOX APPROACH
TEST CASE GENERATION GENERATION BLOCK BOX APPROACH
 
Gravity concentration_MI20612MI_________
Gravity concentration_MI20612MI_________Gravity concentration_MI20612MI_________
Gravity concentration_MI20612MI_________
 
Secure Key Crypto - Tech Paper JET Tech Labs
Secure Key Crypto - Tech Paper JET Tech LabsSecure Key Crypto - Tech Paper JET Tech Labs
Secure Key Crypto - Tech Paper JET Tech Labs
 
Versatile Engineering Construction Firms
Versatile Engineering Construction FirmsVersatile Engineering Construction Firms
Versatile Engineering Construction Firms
 
Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...
Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...
Guardians of E-Commerce: Harnessing NLP and Machine Learning Approaches for A...
 
70 POWER PLANT IAE V2500 technical training
70 POWER PLANT IAE V2500 technical training70 POWER PLANT IAE V2500 technical training
70 POWER PLANT IAE V2500 technical training
 
Machine Learning 5G Federated Learning.pdf
Machine Learning 5G Federated Learning.pdfMachine Learning 5G Federated Learning.pdf
Machine Learning 5G Federated Learning.pdf
 
ADM100 Running Book for sap basis domain study
ADM100 Running Book for sap basis domain studyADM100 Running Book for sap basis domain study
ADM100 Running Book for sap basis domain study
 
Robotics Group 10 (Control Schemes) cse.pdf
Robotics Group 10  (Control Schemes) cse.pdfRobotics Group 10  (Control Schemes) cse.pdf
Robotics Group 10 (Control Schemes) cse.pdf
 
1- Practice occupational health and safety procedures.pptx
1- Practice occupational health and safety procedures.pptx1- Practice occupational health and safety procedures.pptx
1- Practice occupational health and safety procedures.pptx
 
ASME-B31.4-2019-estandar para diseño de ductos
ASME-B31.4-2019-estandar para diseño de ductosASME-B31.4-2019-estandar para diseño de ductos
ASME-B31.4-2019-estandar para diseño de ductos
 
Uk-NO1 kala jadu karne wale ka contact number kala jadu karne wale baba kala ...
Uk-NO1 kala jadu karne wale ka contact number kala jadu karne wale baba kala ...Uk-NO1 kala jadu karne wale ka contact number kala jadu karne wale baba kala ...
Uk-NO1 kala jadu karne wale ka contact number kala jadu karne wale baba kala ...
 
Uk-NO1 Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Exp...
Uk-NO1 Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Exp...Uk-NO1 Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Exp...
Uk-NO1 Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Exp...
 
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
2022 AWS DNA Hackathon 장애 대응 솔루션 jarvis.
 
Indian Tradition, Culture & Societies.pdf
Indian Tradition, Culture & Societies.pdfIndian Tradition, Culture & Societies.pdf
Indian Tradition, Culture & Societies.pdf
 

Direct3D Game Programming C++11 Primer

  • 1. Beginning Direct3D Game Programming: C++11 Primer jintaeks@gmail.com Division of Digital Contents, DongSeo University. March 2016
  • 2. C++11  C++11 is a version of the standard for the programming language C++.  It was approved by International Organization for Standardization (ISO) on 12 August 2011, replacing C++03,[1] and superseded by C++14 on 18 August 2014.[2]  Although one of the design goals was to prefer changes to the libraries over changes to the core language,[4] C++11 does make several additions to the core language. 2
  • 3. Design goals  Maintain stability and compatibility with C++98 and possibly with C.  Prefer introducing new features via the standard library, rather than extending the core language.  Improve C++ to facilitate systems and library design, rather than introduce new features useful only to specific applications. 3
  • 4. Extensions to the C++ core language  Rvalue references and move constructors.  Extern template  Initializer lists  Uniform initializations  Type inference  Ranged-based for loop  Lambda functions and expressions  Alternative function syntax  Explicit override and final  Null pointer constant  Explicit conversion operator  … 4
  • 5. Rvalue references and move constructors  rvalues? as they often lie on the right side of an assignment.  In C++03 and before, temporaries were intended to never be modifiable and were considered to be indistinguishable from const T& types.  C++11 adds a new non-const reference type called an rvalue reference, identified by T&&.  This refers to temporaries that are permitted to be modified after they are initialized, for the purpose of allowing "move semantics". 5
  • 6.  If a std::vector<T> temporary is created or returned from a function, it can be stored only by creating a new std::vector<T> and copying all the rvalue's data into it.  If std::vector<T> is a C++03 version without a move constructor, then the copy constructor will be invoked with a const std::vector<T>&, incurring a significant memory allocation.  Move constructor not only forgoes the expense of a deep copy, but is safe and invisible. 6
  • 7. std::move(), perfect forwarding  For safety reasons, a named variable will never be considered to be an rvalue even if it is declared as such. To get an rvalue, the function template std::move() should be used.  Due to the nature of the wording of rvalue references, and to some modification to the wording for lvalue references (regular references), rvalue references allow developers to provide perfect function forwarding. 7
  • 8. basic concepts of rvalue class KTest { public: KTest() { std::cout << "constructorrn"; } KTest( const KTest& rhs ) { std::cout << "copy constructorrn"; } ~KTest() { std::cout << "destructorrn"; } }; 8
  • 9. KTest F( KTest t ) { return t; } void G( const KTest& t ) { std::cout << "lvalue ref G " << std::endl; } void G( KTest&& t ) { //KTest u = std::move( t ); //KTest u = t; std::cout << "rvalue ref G " << std::endl; } int main() { KTest t; KTest u = t; u = F( KTest() ); std::cout << "rnbefore call Grn"; G( KTest() ); } 9 constructor copy constructor constructor copy constructor destructor destructor before call G constructor lvalue ref G destructor destructor destructor
  • 10. KTest F( KTest t ) { return t; } void G( const KTest& t ) { std::cout << "lvalue ref G " << std::endl; } void G( KTest&& t ) { //KTest u = std::move( t ); //KTest u = t; std::cout << "rvalue ref G " << std::endl; } int main() { KTest t; KTest u = t; u = F( KTest() ); std::cout << "rnbefore call Grn"; G( KTest() ); } 10 constructor copy constructor constructor copy constructor destructor destructor before call G constructor rvalue ref G destructor destructor destructor
  • 11. KTest F( KTest t ) { return t; } void G( const KTest& t ) { std::cout << "lvalue ref G " << std::endl; } void G( KTest&& t ) { KTest u = std::move( t ); //KTest u = t; std::cout << "rvalue ref G " << std::endl; } int main() { KTest t; KTest u = t; u = F( KTest() ); std::cout << "rnbefore call Grn"; G( KTest() ); } 11 We want to call the move constructor of 'u'. A named variable will never be considered to be an rvalue even if it is declared as such. To get an rvalue, the function template std::move() should be used.
  • 12. move constructor struct A { std::string s; A() : s( "test" ) { std::cout << "constructor An"; } A( const A& o ) : s( o.s ) { std::cout << "copy constructor An"; } A( A&& o ) : s( std::move( o.s ) ) { std::cout << "move constructor An"; } }; A f( A a ) { return a; } struct B : public A { std::string s2; int n; }; B g( B b ) { return b; } 12 we expect below things in 'B': * implicit move constructor B::(B&&) * calls A's move constructor * calls s2's move constructor * and makes a bitwise copy of n * but in Visual Studio 2013, implicit functions do not call base class's corresponding functions.
  • 13. int main() { std::cout << "Trying to move An"; A a1 = f( A() ); // move-construct from rvalue temporary std::cout << "Before move, a1.s = " << a1.s << "n"; A a2 = std::move( a1 ); // move-construct from xvalue std::cout << "After move, a1.s = " << a1.s << "n"; std::cout << "Trying to move Bn"; B b1 = g( B() ); std::cout << "Before move, b1.s = " << b1.s << "n"; B b2 = std::move( b1 ); // calls implicit move ctor std::cout << "After move, b1.s = " << b1.s << "n"; } 13 Trying to move A constructor A move constructor A Before move, a1.s = test move constructor A After move, a1.s = Trying to move B constructor A copy constructor A Before move, b1.s = test copy constructor A After move, b1.s = test
  • 14. struct A { std::string s; A() : s( "test" ) { std::cout << "constructor An"; } A( const A& o ) : s( o.s ) { std::cout << "copy constructor An"; } A( A&& o ) : s( std::move( o.s ) ) { std::cout << "move constructor An"; } }; struct C : public A { std::string s2; int n; C() : A() { std::cout << "constructor Cn"; } C( const C& o ) : A( o ) { std::cout << "copy constructor Cn"; } C( C&& o ) : A( std::move( o ) ) { std::cout << "move constructor Cn"; } //C( C&& o ) : A( o ) { std::cout << "move constructor Cn"; } }; 14
  • 15. KTest u = t; differs from u = t; class KTest { public: KTest() { std::cout << "constructorrn"; } KTest( const KTest& rhs ) { std::cout << "copy constructorrn"; } ~KTest() { std::cout << "destructorrn"; } KTest& operator=( const KTest& rhs ) { std::cout << "operator=rn"; return *this; } }; int main() { KTest t; KTest u = t; KTest v; v = t; // this is same as v.operator=(t); }15 constructor copy constructor constructor operator= destructor destructor destructor
  • 16. real world example class MemoryBlock { public: explicit MemoryBlock( size_t length ) : _length( length ) , _data( new int[ length ] ) { std::cout << "In MemoryBlock(size_t). length = " << _length << "." << std::endl; } // Destructor. ~MemoryBlock() { std::cout << "In ~MemoryBlock(). length = " << _length << "."; if( _data != nullptr ) { std::cout << " Deleting resource."; // Delete the resource. delete[] _data; _data = nullptr; } std::cout << std::endl; } 16
  • 17. MemoryBlock( const MemoryBlock& other ) : _length( other._length ) , _data( new int[ other._length ] ) { std::cout << "In MemoryBlock(const MemoryBlock&). length = " << other._length << ". Copying resource." << std::endl; std::copy( other._data, other._data + _length, _data ); } MemoryBlock& operator=( const MemoryBlock& other ) { std::cout << "In operator=(const MemoryBlock&). length = " << other._length << ". Copying resource." << std::endl; if( this != &other ) { delete[] _data; _length = other._length; _data = new int[ _length ]; std::copy( other._data, other._data + _length, _data ); } return *this; }17
  • 18. // Move constructor. MemoryBlock( MemoryBlock&& other ) : _data( nullptr ) , _length( 0 ) { std::cout << "In MemoryBlock(MemoryBlock&&). length = " << other._length << ". Moving resource." << std::endl; // Copy the data pointer and its length from the // source object. _data = other._data; _length = other._length; // Release the data pointer from the source object so that // the destructor does not free the memory multiple times. other._data = nullptr; other._length = 0; } 18
  • 19. // Move assignment operator. MemoryBlock& operator=( MemoryBlock&& other ) { std::cout << "In operator=(MemoryBlock&&). length = " << other._length << "." << std::endl; if( this != &other ) { // Free the existing resource. delete[] _data; // Copy the data pointer and its length from the // source object. _data = other._data; _length = other._length; // Release the data pointer from the source object so that // the destructor does not free the memory multiple times. other._data = nullptr; other._length = 0; } return *this; } 19
  • 20. Modification to the definition of plain old data  In C++03, a class or struct must follow a number of rules for it to be considered a plain old data(POD) type.  Types that fit this definition produce object layouts that are compatible with C, and they could also be initialized statically.  if someone were to create a C++03 POD type and add a non- virtual member function, this type would no longer be a POD type.  C++11 relaxed several of the POD rules, by dividing the POD concept into two separate concepts:trivial and standard- layout. 20 A class with complex move and copy constructors may not be trivial, but it could be standard- layout and thus interop with C.
  • 21. trivial  it is legal to copy data around via memcpy, rather than having to use a copy constructor. ① Has a trivial default constructor. This may use the default constructor syntax(SomeConstructor() = default;). ② Has trivial copy and move constructors, which may use the default syntax. ③ Has trivial copy and move assignment operators, which may use the default syntax. ④ Has a trivial destructor, which must not be virtual. 21
  • 22. standard-layout  It orders and packs its members in a way that is compatible with C. ① It has no virtual functions ② It has no virtual base classes ③ All its non-static data members have the same access control (public, private, protected) ④ All its non-static data members, including any in its base classes, are in the same one class in the hierarchy ⑤ The above rules also apply to all the base classes and to all non-static data members in the class hierarchy ⑥ It has no base classes of the same type as the first defined non-static data member 22
  • 23. #include <type_traits> struct X { // It means that you want to use the compiler-generated version // of that function, so you don't need to specify a body. X() = default; }; struct Y { Y() {}; }; int main() { static_assert( std::is_trivial<X>::value, "X should be trivial" ); static_assert( std::is_pod<X>::value, "X should be POD" ); static_assert( !std::is_trivial<Y>::value, "Y should not be trivial" ); static_assert( !std::is_pod<Y>::value, "Y should not be POD" ); } 23
  • 24. Extern template  In C++03, the compiler must instantiate a template whenever a fully specified template is encountered in a translation unit.  If the template is instantiated with the same types in many translation units, this can dramatically increase compile times.  C++11 now provides this syntax: extern template class std::vector<MyClass>; 24
  • 25. Initializer lists  C++03 inherited the initializer-list feature from C. A struct or array is given a list of arguments in braces, in the order of the members' definitions in the struct. struct Object { float first; int second; }; Object scalar = {0.43f, 10}; //One Object, with first=0.43f and second=10 Object anArray[] = {{13.4f, 3}, {43.28f, 29}, {5.934f, 17}}; //An array of three Objects 25
  • 26.  C++03 allows initializer-lists only on structs and classes that conform to the Plain Old Data (POD) definition.  C++11 extends initializer-lists, so they can be used for all classes including standard containers like std::vector. class SequenceClass { public: SequenceClass(std::initializer_list<int> list); }; SequenceClass some_var = {1, 4, 5, 6};  This constructor is a special kind of constructor, called an initializer-list-constructor. Classes with such a constructor are treated specially during uniform initialization. 26
  • 27. first-class citizen  In programming language design, a first-class citizen (also type, object, entity, or value) in a given programming language is an entity which supports all the operations generally available to other entities.  The simplest scalar data types, such as integer and floating- point numbers, are nearly always first-class.  In C++, arrays is not first-class: they cannot be assigned as objects or passed as parameters to a subroutine.  For example, C++ doesn't supports array assignment, and when they are passed as parameters, only the position of their first element is actually passed—their size is lost. 27
  • 28.  The class std::initializer_list<> is a first-class C++11 standard library type.  However, they can be initially constructed statically by the C++11 compiler only via use of the {} syntax. void function_name(std::initializer_list<float> list); function_name({1.0f, -3.45f, -0.4f});  Standard containers can also be initialized in these ways: std::vector<std::string> v = { "xyzzy", "plugh", "abracadabra" }; std::vector<std::string> v({ "xyzzy", "plugh", "abracadabra" }); std::vector<std::string> v{ "xyzzy", "plugh", "abracadabra" }; 28
  • 29. My own initializer_list? 29 The initializer_list is a real type, it can be used in other places besides class constructors. Regular functions can take typed initializer lists as arguments. But! std::initializer_list is treated specially. So you can not create your own initializer_list.
  • 30. Uniform initialization  C++03 has a number of problems with initializing types. Several ways to do this exist, and some produce different results when interchanged.  For example, The traditional constructor syntax can look like a function declaration.  Only aggregates and POD types can be initialized with aggregate initializers (using SomeType var = {/*stuff*/};). 30
  • 31.  C++11 provides a syntax that allows for fully uniform type initialization that works on any object. struct BasicStruct { int x; double y; }; struct AltStruct { AltStruct(int x, double y) : x_{x}, y_{y} {} private: int x_; double y_; }; BasicStruct var1{5, 3.2}; AltStruct var2{2, 4.3}; 31 struct IdString { std::string name; int identifier; }; IdString get_string() { return {"foo", 42}; //Note the lack of explicit type. }
  • 32.  The following code will call the initializer list constructor, not the constructor of std::vector that takes a single size parameter and creates the vector with that size. std::vector<int> the_vec{4}; 32
  • 33. Type inference: decltype  In C++03 (and C), to use a variable, its type must be specified explicitly.  However, with the advent of template types and template metaprogramming techniques, the type of something, particularly the well-defined return value of a function, may not be easily expressed. 33
  • 34. well-defined  In mathematics, an expression is called well-defined if its definition assigns it a unique interpretation or value. Otherwise, the expression is said to be not well-defined .  A function is well-defined if it gives the same result when the representation of the input is changed without changing the value of the input.  For instance if f takes real numbers as input, and if f(0.5) does not equal f(1/2) then f is not well-defined. 34
  • 35.  C++11 allows this to be mitigated in two ways. First, the definition of a variable with an explicit initialization can use the auto keyword. auto some_strange_callable_type = std::bind(&some_function, _2, _1, some_object); auto other_variable = 5; for (std::vector<int>::const_iterator itr = myvec.cbegin(); itr != myvec.cend(); ++itr) for (auto itr = myvec.cbegin(); itr != myvec.cend(); ++itr)  Further, the keyword decltype can be used to determine the type of expression at compile-time. int some_int; decltype(some_int) other_integer_variable = 5; 35
  • 36. when to use // will not compiled! template<typename T, typename U> decltype(T+U) add( T t, U u ) { return t + u; } template<typename T, typename U> auto add2( T t, U u ) -> decltype( t + u ) // return type depends on template parameters { return t + u; } 36
  • 37. template<typename T, typename U> auto add2( T t, U u ) -> decltype( t + u ) // return type depends on template parameters { return t + u; } int main() { printf( "%i %irn", i, j ); auto f = []( int a, int b ) -> int { return a * b; }; decltype( f ) g = f; // the type of a lambda function is unique and unnamed i = f( 2, 2 ); j = g( 3, 3 ); printf( "%i %irn", i, j ); std::cout << add2( 2, 3 ) << std::endl; } 37 3 6 4 9 5
  • 38. Alternative function syntax  In C++03 this is disallowed. template<class Lhs, class Rhs> Ret adding_func(const Lhs &lhs, const Rhs &rhs) {return lhs + rhs;} //Ret must be the type of lhs+rhs  Even with the aforementioned C++11 functionality of decltype, this is not possible: template<class Lhs, class Rhs> decltype(lhs+rhs) adding_func(const Lhs &lhs, const Rhs &rhs) {return lhs + rhs;} //Not legal C++11 38
  • 39. trailing-return-type  To work around this, C++11 introduced a new function declaration syntax, with a trailing-return-type: template<class Lhs, class Rhs> auto adding_func(const Lhs &lhs, const Rhs &rhs) -> decltype(lhs+rhs) {return lhs + rhs;}  This syntax can be used for more mundane function declarations and definitions. struct SomeStruct { auto func_name(int x, int y) -> int; }; auto SomeStruct::func_name(int x, int y) -> int { return x + y; } 39
  • 40. Range-based for loop  C++11 extends the syntax of the for statement to allow for easy iteration over a range of elements. int my_array[5] = {1, 2, 3, 4, 5}; // double the value of each element in my_array: for (int &x : my_array) { x *= 2; } // similar but also using type inference for array elements for (auto &x : my_array) { x *= 2; }  It will work for C-style arrays, initializer lists, and any type that has begin() and end() functions defined for it that return iterators. 40
  • 41. my own container can be used in range-based for loop template<class T> class MyVector { public: typedef T* iterator; public: T m_data[ 100 ]; int m_begin; int m_end; MyVector(); T& operator[]( int i ) { return m_data[ i ]; } void push_back( T& d ); T* begin(); T* end(); };//class MyVector 41 class CData { int data; public: CData( int d = 0 ) : data(d) {} void DoIt() { printf( "data=%dn", data ); }//DoIt() };//class CTest
  • 42. template<class T> MyVector<T>::MyVector() { m_begin = 0; m_end = 0; } template<class T> void MyVector<T>::push_back( T& d ) { m_data[ m_end++ ] = d; } template<class T> T* MyVector<T>::begin() { return &m_data[ m_begin ]; } template<class T> T* MyVector<T>::end() { return &m_data[ m_end ]; } 42 void main() { CData d1( 1 ), d2( 2 ), d3( 3 ); MyVector<CData> vec; vec.push_back( d1 ); vec.push_back( d2 ); vec.push_back( d3 ); vec[ 1 ].DoIt(); for( CData& d : vec ) { d.DoIt(); } }//main()
  • 43. Lambda functions and expressions  C++11 provides the ability to create anonymous functions, called lambda functions. These are defined as follows: [](int x, int y) -> int { return x + y; }  The return type of lambda can be omitted as long as all return expressions return the same type. A lambda can optionally be a closure. 43
  • 44. when to use int CompFunc( int left_, int right_ ) { return left_ < right_; } class KCompare { public: int operator()( int left_, int right_ ) const { return left_ < right_; } }; template<typename T> void CompareTest( int a, int b, T predicate_ ) { //const bool bCompResult = predicate_.operator()(a, b); const bool bCompResult = predicate_( a, b ); printf( "CompareTest result = %drn", bCompResult ); } int main() { CompareTest( 2, 3, CompFunc ); CompareTest( 2, 3, KCompare() ); } 44
  • 45. template<typename T> void CompareTest( int a, int b, T predicate_ ) { //const bool bCompResult = predicate_.operator()(a, b); const bool bCompResult = predicate_( a, b ); printf( "CompareTest result = %drn", bCompResult ); } int main() { auto compareLambda = []( int a, int b )->int {return a < b; }; CompareTest( 2, 3, compareLambda ); CompareTest( 2, 3, []( int a, int b )->int {return a < b; } ); } 45
  • 46. capture list [capture](parameters) -> return_type { function_body } [] //no variables defined. Attempting to use any external variables in the lambda is an error. [x, &y] //x is captured by value, y is captured by reference [&] //any external variable is implicitly captured by reference if used [=] //any external variable is implicitly captured by value if used [&, x] //x is explicitly captured by value. Other variables will be captured by reference [=, &z] //z is explicitly captured by reference. Other variables will be captured by value 46
  • 47. int main() { std::vector<int> some_list{ 1, 2, 3, 4, 5 }; int total = 0; std::for_each( begin( some_list ), end( some_list ), [&total]( int x ) { total += x; } ); printf( "%irn", total ); } 47 class KTest { public: int some_func() const { return 2; } void Test() { std::vector<int> some_list{ 1, 2, 3, 4, 5 }; int total = 0; int value = 5; std::for_each( begin( some_list ), end( some_list ), [&, value, this]( int x ) { total += x * value * this->some_func(); } ); } };
  • 48.  This will cause total to be stored as a reference, but value will be stored as a copy.  The capture of this is special. It can only be captured by value, not by reference. this can only be captured if the closest enclosing function is a non-static member function.  A lambda expression with an empty capture specification ([]) can be implicitly converted into a function pointer with the same type as the lambda was declared with. auto a_lambda_func = [](int x) { /*...*/ }; void (* func_ptr)(int) = a_lambda_func; func_ptr(4); //calls the lambda. 48
  • 49. various usage of lambda std::function<double( double )> f0 = []( double x ) {return 1; }; auto f1 = []( double x ) {return x; }; decltype( f0 ) fa[ 3 ] = { f0, f1, []( double x ) {return x*x; } }; std::vector<decltype( f0 )> fv = { f0, f1 }; fv.push_back( []( double x ) {return x*x; } ); for( int i = 0; i<fv.size(); i++ ) std::cout << fv[ i ]( 2.0 ) << std::endl; for( int i = 0; i<3; i++ ) std::cout << fa[ i ]( 2.0 ) << std::endl; for( auto &f : fv ) std::cout << f( 2.0 ) << std::endl; for( auto &f : fa ) std::cout << f( 2.0 ) << std::endl; std::cout << eval( f0 ) << std::endl; std::cout << eval( f1 ) << std::endl; std::cout << eval( []( double x ) {return x*x; } ) << std::endl; 49
  • 50. Object construction improvement  In C++03, constructors of a class are not allowed to call other constructors of that class.  C++11 allows constructors to call other peer constructors (termed delegation). class SomeType { int number; public: SomeType(int new_number) : number(new_number) {} SomeType() : SomeType(42) {} }; 50
  • 51.  For member initialization, C++11 allows this syntax: class SomeClass { public: SomeClass() {} explicit SomeClass(int new_value) : value(new_value) {} private: int value = 5; }; 51
  • 52. Explicit overrides and final  In C++03, it is possible to accidentally create a new virtual function, when one intended to override a base class function. struct Base { virtual void some_func(float); }; struct Derived : Base { virtual void some_func(int); };  Because it has a different signature, it creates a second virtual function. struct Base { virtual void some_func(float); }; struct Derived : Base { virtual void some_func(int) override; // ill-formed - doesn't override a base class method }; 52
  • 53.  C++11 also adds the ability to prevent inheriting from classes or simply preventing overriding methods in derived classes. This is done with the special identifier final. struct Base1 final { }; struct Derived1 : Base1 { }; // ill-formed because the class Base1 has been marked final struct Base2 { virtual void f() final; }; struct Derived2 : Base2 { void f(); // ill-formed because the virtual function Base2::f has been marked final }; 53
  • 54. Null pointer constant  Since the dawn of C in 1972, the constant 0 has had the double role of constant integer and null pointer constant.  The ambiguity inherent in the double meaning of 0 was dealt with in C by using the preprocessor macro NULL, which commonly expands to either ((void*)0) or 0. void foo(char *); void foo(int);  If NULL is defined as 0, the statement foo(NULL); will call foo(int), which is almost certainly not what the programmer intended.  C++11 corrects this by introducing a new keyword to serve as a distinguished null pointer constant: nullptr. It is of type nullptr_t, which is implicitly convertible and comparable to any pointer type or pointer-to-member type. 54
  • 55. class KPointer { public: template<typename T> KPointer& operator=( T rhs ) = delete; KPointer& operator=( char* rhs ) { m_pData = rhs; return *this; } // do not use like this. it's just example. KPointer& operator=( nullptr_t rhs ) { delete m_pData; m_pData = nullptr; return *this; } public: char* m_pData; }; 55 int main() { KPointer t; t = new char; //t = 0; // compile time error! t = nullptr; return 0; }
  • 56. Strongly typed enumerations  In C++03, enumerations are not type-safe.  They are effectively integers, even when the enumeration types are distinct.  This allows the comparison between two enum values of different enumeration types.  The underlying integral type is implementation-defined.  C++11 allows a special classification of enumeration that has none of these issues. This is expressed using the enum class. 56
  • 57. enum class Enumeration { Val1, Val2, Val3 = 100, Val4 // = 101 };  This enumeration is type-safe. Enum class values are not implicitly converted to integers. Thus, they cannot be compared to integers either.  The underlying type of enum classes is always known. The default type is int; this can be overridden to a different integral type. enum class Enum2 : unsigned int {Val1, Val2}; 57
  • 58. Right angle bracket  C++03's parser defines “>>” as the right shift operator in all cases.  C++11 improves the specification of the parser so that multiple right angle brackets will be interpreted as closing the template argument list where it is reasonable. template<bool Test> class SomeType; std::vector<SomeType<1>2>> x1; /* Interpreted as a std::vector of SomeType<true>, followed by "2 >> x1", which is not legal syntax for a declarator. 1 is true. */ 58
  • 59. Explicit conversion operators  C++98 added the explicit keyword as a modifier on constructors to prevent single-argument constructors from being used as implicit type conversion operators.  However, this does nothing for actual conversion operators.  For example, a smart pointer class may have an operator bool() to allow it to act more like a primitive pointer: if it includes this conversion, it can be tested with if (smart_ptr_variable) (which would be true if the pointer was non-null and false otherwise).  However, this allows other, unintended conversions as well.  (We will look into more detail later in this presentation). 59
  • 60. Template aliases  In C++03, it is not possible to create a typedef template. template <typename First, typename Second, int Third> class SomeType; template <typename Second> typedef SomeType<OtherType, Second, 5> TypedefName; // Illegal in C++03  C++11 adds this ability with this syntax. template <typename First, typename Second, int Third> class SomeType; template <typename Second> using TypedefName = SomeType<OtherType, Second, 5>;  The using syntax can be also used as type aliasing in C++11: typedef void (*FunctionType)(double); // Old style using FunctionType = void (*)(double); // New introduced syntax 60
  • 61. Variadic templates  C++11 allows template definitions to take an arbitrary number of arguments of any type. template<typename... Values> class tuple;  The above template class tuple can be used like this: tuple<int, std::vector<int>, std::map<<std::string>, std::vector<int>>> some_instance_name; 61
  • 62. ellipsis operator (…) Probably the most famous function in both C & C++ to take advantage of this mechanism is printf-function in C standard library: int printf (const char* format, ... ); Ellipsis mechanism can also be used with preprocessor in a form of a macro. A macro taking a variable number of parameters is called a variadic macro. #define VARIADIC_MACRO(...) In C++, this ellipsis operator got a new meaning in different context called exception handling. The operator is used in catch blocks after try blocks: try{ // Try block. } catch(...){ // Catch block. } 62
  • 63. now ellipsis (…) can be used in C++11 template  The ellipsis (...) operator has two roles: – When it occurs to the left of the name of a parameter, it declares a parameter pack. – Using the parameter pack, the user can bind zero or more arguments to the variadic template parameters. – When the ellipsis operator occurs to the right of a template or function call argument, it unpacks the parameter packs into separate arguments.  Another operator used with variadic templates is the sizeof...- operator. sizeof... operator can be used to determine the amount of types given into a variadic template. template<typename... Arguments> class VariadicTemplate{ private: static const unsigned short int size = sizeof...(Arguments); }; 63
  • 64. simple example: variadic function template template<typename T> T adder( T v ) { return v; } template<typename T, typename... Args> T adder( T first, Args... args ) { return first + adder( args... ); } void main() { long sum = adder( 1, 2, 3, 8, 7 ); printf( "%irn", sum ); std::string s1 = "x", s2 = "aa", s3 = "bb", s4 = "yy"; std::string ssum = adder( s1, s2, s3, s4 ); printf( "%srn", ssum.c_str() ); } 64
  • 65. variadic template version of printf() void printf2( const char *s ) { while( *s ) { if( *s == '%' ) { if( *( s + 1 ) == '%' ) { ++s; } else { throw std::runtime_error( "invalid format string: missing arguments" ); } } std::cout << *s++; } } 65
  • 66. template<typename T, typename... Args> void printf2( const char *s, T value, Args... args ) { while( *s ) { if( *s == '%' ) { if( *( s + 1 ) == '%' ) { ++s; } else { std::cout << value; s += 2; // this only works on 2 characters format strings ( %d, %f, etc ). Fails miserably with %5.4f printf2( s, args... ); // call even when *s == 0 to detect extra arguments return; } } std::cout << *s++; } } 66
  • 67. variadic class template template<bool B, class T, class F> struct conditional { typedef T type; }; template<class T, class F> struct conditional<false, T, F> { typedef F type; }; template <typename... Args> struct find_biggest; // the biggest of one thing is that one thing template <typename First> struct find_biggest<First> { typedef First type; }; template <typename First, typename... Args> struct find_biggest<First, Args...> { typedef typename conditional< sizeof( First ) >= sizeof( typename find_biggest<Args...>::type ) , First, typename find_biggest<Args...>::type>::type type; }; 67
  • 68. // the biggest of everything in Args and First template <typename First, typename... Args> struct find_biggest<First, Args...> { static const int size = sizeof...( Args ) + 1; typedef typename find_biggest<Args...>::type next; typedef typename conditional< sizeof( First ) >= sizeof(next) , First, next>::type type; }; void main() { find_biggest<char, long long, float, short>::type i; printf( "%irn", sizeof( i ) ); // 8 printf( "%i %irn", sizeof( i ) // 5 , find_biggest<char, long long, float, short>::size ); } 68
  • 69. New string literals  It is also sometimes useful to avoid escaping strings manually, particularly for using literals of XMLfiles, scripting languages, or regular expressions.  C++11 provides a raw string literal: #include <stdio.h> void main() { char* p0 = R"(The String Data Stuff " rn)"; char* p1 = R"delimiter(The String Data Stuff " rn)delimiter"; printf( "%srn", p0 ); printf( "%srn", p1 ); } 69
  • 70. Thread-local storage  In addition to the existing static, dynamic and automatic.  A new thread-local storage duration is indicated by the storage specifier thread_local.  Microsoft Visual Studio 2013 doesn't support thread_local, instead you can use __declspec(thread). 70
  • 71. we want to maintain g_pData for each thread. How? #include <iostream> #include <thread> #include <windows.h> int* g_pData = nullptr; void foo( int i ) { if( g_pData == nullptr ) { g_pData = new int[ 11 ]; printf( "g_pData allocated %irn", i ); } Sleep( 500 ); printf( "%irn", i ); if( g_pData != nullptr ) { delete[] g_pData; printf( "g_pData destroyed %irn", i ); } } 71 int main() { std::thread first( foo, 1 ); std::thread second( foo, 3 ); std::cout << "main, foo and foo now execute concurrently...n"; // synchronize threads: first.join(); // pauses until first finishes second.join(); // pauses until second finishes std::cout << "foo and bar completed.n"; return 0; }
  • 72.  If you want to maintain the single g_pData, you must add thread safety features. 72
  • 73. __declspec(thread) int* g_pData = nullptr; void foo( int i ) { if( g_pData == nullptr ) { g_pData = new int[ 11 ]; printf( "g_pData allocated %irn", i ); } Sleep( 500 ); printf( "%irn", i ); if( g_pData != nullptr ) { delete[] g_pData; printf( "g_pData destroyed %irn", i ); } } int main() { std::thread first( foo, 1 ); std::thread second( foo, 3 ); std::cout << "main, foo and foo now execute concurrently...n"; 73 // synchronize threads: first.join(); // pauses until first finishes second.join(); // pauses until second finishes std::cout << "foo and bar completed.n"; return 0; } g_pData allocated 1 g_pData allocated 3 main, foo and foo now execute concurrently... 1 g_pData destroyed 1 3 g_pData destroyed 3 foo and bar completed.
  • 74. Explicitly defaulted and deleted special member function  For classes that do not provide them for themselves:  In C++03, the compiler provides, a default constructor, a copy constructor, a copy assignment operator (operator=), and a destructor. The programmer can override these defaults by defining custom versions.  C++11 allows the explicit defaulting and deleting of these special member functions.  The = delete specifier can be used to prohibit calling any function, which can be used to disallow calling a member function with particular parameters. 74
  • 75. famous usage #include <iostream> #include <vector> #include <algorithm> #include <functional> class KData { public: KData( const KData& rhs ) = delete; KData& operator=( const KData& rhs ) = delete; KData( int i ) : m_iData{ i } {} public: int m_iData = 0; }; int main() { std::vector<KData> v; v.push_back( { 1 } ); // will not be compiled! return 0; } 75
  • 76. Type long long int  This resulted in long int having size of 64 bits on some popular implementations and 32 bits on others.  C++11 adds a new integer type long long int to address this issue. It is guaranteed to be at least as large as a long int, and have no fewer than 64 bits. 76
  • 77. Static assertions  The new utility introduces a new way to test assertions at compile-time, using the new keyword static_assert. template<class T> struct Check { static_assert(sizeof(int) <= sizeof(T), "T is not big enough!"); }; 77
  • 78. C++ standard library changes  Threading facilities  General-purpose smart pointers  Wrapper reference  Type traits for metaprogramming 78
  • 79. Allow garbage collected implementations  When someday, garbage collector added into the C++ library. We need to tell to the garbage collector about that do not delete 'p' pointer it will be reachable later in my code.  To tell this, we need to call std::declare_reachable(p);.  In previous example, if we do not call std::declare_reachable(p);, the pointer 'p' to dynamic object can be destroyed by the garbage collector due to there is no live pointer to dynamic object by 'scrambling p' statement.  To prevent this situation, we must tell to the garbage collector about reachableness of pointer to dynamic object.  std::declare_reachable() is used for this purpose. 79
  • 80. int main() { int * p = new int( 1 ); // dynamic object std::declare_reachable( p ); p = (int*)( ( std::uintptr_t )p ^ UINTPTR_MAX ); // scrambling p // dynamic object not reachable by any live safely-derived pointer p = std::undeclare_reachable( (int*)( ( std::uintptr_t )p ^ UINTPTR_MAX ) ); // p is back again a safely-derived pointer to the dynamic object std::cout << "p: " << *p << 'n'; delete p; return 0; } 80
  • 81. General-purpose smart pointers  std::shared_ptr  std::weak_ptr  std::unique_ptr 81
  • 82. void 참조를 특화로 구현 82 template<class T> struct shared_ptr_traits { typedef T& reference; }; template<> struct shared_ptr_traits<void> { typedef void reference; };  void타입에 대한 reference가 가능하도록 템플릿 특화specialization을 사용하여 미리 구현해 둡니다.  기타 type-trait에 대한 설명은 생략합니다.
  • 83. shared_ptr: 생성자 구현 83 template<class T> class shared_ptr { public: typedef shared_ptr<T> this_type; typedef T value_type; typedef T* pointer; typedef typename shared_ptr_traits<T>::reference reference; public: shared_ptr(T * p = 0) : px(p), pn(0) { if( px != NULL ) pn = new int(1); }  생성자에서는 전달받은 raw pointer를 초기화합니다.  참조 카운팅을 위한 메모리 할당을 하고, 참조 카운터를 1로 초기화합니다.
  • 84. shared_ptr: 복사 생성자와 파괴자 구현 84 shared_ptr( const shared_ptr& right_ ) : px( 0 ), pn( 0 ) { release(); px = right_.px; pn = right_.pn; if( px != NULL ) *pn += 1; } ~shared_ptr() { release(); }  복사 생성자는 먼저 이전에 할당되어 있는 리소스를 해제 합니다.  새로운 리소스에 대한 참조를 설정하고, 참조 카운터를 증가시킵니다.
  • 85. shared_ptr: operator=(), operator pointer() 85 shared_ptr& operator=( const shared_ptr& right_ ) { release(); px = right_.px; pn = right_.pn; if( px != NULL ) *pn += 1; return *this; } operator pointer() const { return px; }  대입 연산자는 복사 생성자와 거의 동일하게 구현합니다.  타입에 대한 포인터 연산이 제대로 동작하도록 operator T*()를 정의합니다.
  • 86. shared_ptr: release() 구현 86 void release() { if( px != NULL && *pn >= 1 ) { *pn -= 1; if( *pn == 0 ) { delete px; px = NULL; delete pn; pn = NULL; }//if }//if px = NULL; pn = NULL; }  release()는 먼저 참조 카운터를 감소합니다.  참조 카운터가 0이되면, 실제 리소스를 해제 합니다.
  • 87. shared_ptr: reset(), use_count() 구현 87 void reset() { release(); } void reset(T * p) { release(); px = p; pn = NULL; if( px != NULL ) pn = new int(1); } int use_count() const { return *pn; }  reset()은 해제 후 할당과 동일합니다.  완성된 shared_ptr은 암시적 생성implicit construction을 지원하지 않으므로, reset()구현이 반드시 필요합니다.  use_count()는 현재 참조 카운터를 리턴합니다.
  • 88. shared_ptr: operator*(), operator->() 구현 88 reference operator*() const // never throws { return *px; } T* operator->() const // never throws { return px; } private: T* px; int* pn; };//template<class T> class shared_ptr  간접지정 연산자와 화살표 연산자가 제대로 동작하도록 함수를 작성합니다.  void*에 대한 참조가 동작하도록 하기 위해서는 void에 대한 참조를 템플릿 특화로 미리 구현해 두어야 합니다.
  • 89. main()에서 테스트 89 int main() { typedef shared_ptr<int> IntPtr; IntPtr spInt = new int(3); // spInt.use_count() == 1 if( spInt != NULL ) { std::cout << *spInt << std::endl; // 3 }//if IntPtr spInt2 = spInt; // spInt.use_count() == 2 IntPtr spInt3 = spInt; // spInt.use_count() == 3 spInt.reset( new int(4) ); // spInt.use_count() == 1 *spInt = 5; // 3 changed to 5 if( spInt2 != NULL ) // spInt2.use_count() == 2 { std::cout << *spInt2 << std::endl; // 3 }//if return 0; }//int main()
  • 90. copy-and-swap: swap() 메서드 구현 90 void swap( shared_ptr<T>& right_ ) // never throws { std::swap( px, right_.px ); std::swap( pn, right_.pn ); }  exception safety 1) Basic: component의 invariant는 보존되고, resource leak은 발생하지 않아야 합니다. 2) Strong: 성공적으로 완료되었던지 예외를 던졌던지 둘 중의 하나여야 합니다. 3) No-throw: 예외를 던지지 않아야 합니다.  copy-and-swap을 지원하기 위해서 shared_ptr의 swap()은 예외를 던지지 않도록 구현해야 합니다.
  • 91. shared_ptr: swap()을 반영한 수정 91 shared_ptr& operator=( const shared_ptr& right_ ) { //release(); //px = right_.px; //pn = right_.pn; //if( px != NULL ) // *pn += 1; this_type(right_).swap(*this); return *this; } void reset(T * p) { //release(); //px = p; //pn = NULL; //if( px != NULL ) // pn = new int(1); this_type(p).swap(*this); }
  • 92. 관찰: if의 조건문 표현식 92 class KBoolTest { public: operator bool() const { return true; } operator int() const { return 1; } operator int*() const { return NULL; } int GetValue() const { return 9; } }; int main() { KBoolTest t; if( t ) std::cout << t.GetValue() << std::endl; return 0; }//int main()  if문의 조건은 일반적인 bool 표현식이 아닌 C가 허용하는 참인 조건식을 적을 수 있습니다.  평가의 partial order의 순서는 bool  native type  pointer의 순입니다.
  • 93. safe bool idiom 93 //int* p = spInt; // (1) //if( spInt < spInt ) // (2) //{ //}  지금까지의 구현은 (1)과 (2)처럼 잘못된 사용이나, 의미없는 bool 표현식을 막지 못합니다. template <typename T> void some_func(const T& t) { if (t) t->print(); }  smart pointer T에 대해 이 문장이 동작하려면 T는 bool형에 대한 형 변환 연산자를 제공해야 합니다.
  • 94. 해결시도1: operator bool() 구현 94 class Testable { bool ok_; public: explicit Testable(bool b=true):ok_(b) {} operator bool() const { return ok_; } };  shared_ptr은 자신이 valid한 raw pointer를 가질 때, true를 리턴하는 operator bool()을 작성할 수 있습니다.
  • 95. operator bool() cont. 95 test << 1; // (1) int i=test; // (2) Testable a; AnotherTestable b; if (a==b) { // (3) } if (a<b) { // (4) }  이 구현은 (1), (2) 같은 의미 없는 문장이나, (3), (4) 같은 의미 없는 bool 검사를 막지 못합니다.
  • 96. 해결시도2: operator void*()구현 96 operator void*() const { return ok_==true ? this : 0; }  이 구현은 영리해 보이지만, 아래의 문장처럼 delete를 직접호출 할 수 있는 약점을 가집니다. Testable test; delete test;
  • 97. 해결시도3: nested class 97 class Testable { bool ok_; public: explicit Testable(bool b=true):ok_(b) {} class nested_class; operator const nested_class*() const { return ok_ ? reinterpret_cast<const nested_class*>(this) : 0; } }; Testable b1,b2; if (b1==b2) { } if (b1<b2) { }  safe bool을 위한 nested class 구현 역시 의미없는 bool 검사를 막지 못합니다.  이 문제를 해결하려면 포인터 형변환이 되지만, < 같은 비교 연산자를 지원하지 않는 데이터 타입을 사용하는 것입니다.  흥미롭게도 멤버 함수에 대한 포인터가 그렇게 동작합니다!
  • 98. 최종 버전: safe bool idiom 98 class Testable { bool ok_; typedef void (Testable::*bool_type)() const; void this_type_does_not_support_comparisons() const {} public: explicit Testable(bool b=true):ok_(b) {} operator bool_type() const { return ok_==true ? &Testable::this_type_does_not_support_comparisons : 0; } };  if-문장의 조건 표현식에 포인터가 사용될 수 있는 점을 이용하여, 함수 포인터를 리턴하는 연산자 함수를 정의합니다.
  • 99. shared_ptr의 내부: unspecified_bool_type 사용 99 //operator pointer() const //{ // return px; //} void unspecified_bool() const { } typedef void (shared_ptr::*unspecified_bool_type)() const; operator unspecified_bool_type() const // never throws { return px == 0 ? 0 : &shared_ptr::unspecified_bool; }  boost의 실제 코드는 unspecified_bool_type()을 사용합니다.  C++ 표준 라이브러리 뿐만 아니라, 게임 엔진의 스마트 포인터 구현은 모두 이러한 기법을 사용합니다.
  • 100. shared_ptr에 적용된 safe bool idiom 100 typedef shared_ptr<int> IntPtr; IntPtr spInt = new int(3); IntPtr spInt2 = spInt; IntPtr spInt3 = spInt; spInt.reset( new int(4) ); *spInt = 5; if( spInt2 != NULL ) { std::cout << *spInt << std::endl; }//if int* p = spInt; // (1) error if( spInt2 < spInt3 ) // (2) error { }  이제 (1)과 (2)같은 의미 없는 문장은 컴파일 시간 에러가 발생합니다.
  • 101. implicit constructor문제 해결하기 101 void Test( shared_ptr<int> spInt_ ) { } int iData = 5; Test( &iData );  실제 포인터가 아닌, 포인터 표현식에 대한 shared_ptr 생성을 막을 필요가 있습니다.  이 문제에 대한 해결방법은 명시적 생성만 가능하도록 클래스를 설계하는 것입니다. explicit shared_ptr(T * p = 0) : px(p), pn(0) { if( px != NULL ) pn = new int(1); }
  • 102. Wrapper reference  A wrapper reference is obtained from an instance of the template class reference_wrapper.  Wrapper references are similar to normal references (‘&’) of the C++ language. To obtain a wrapper reference from any object the function template std::ref is used. 102
  • 103. #include <iostream> // This function will obtain a reference to the parameter 'r' and increment it. void func( int &r ) { r++; } // Template function. template<class F, class P> void g( F f, P t ) { f( t ); } int main() { int i = 0; g( func, i ); // 'g<void (int &r), int>' is instantiated // then 'i' will not be modified. std::cout << i << std::endl; // Output -> 0 g( func, std::ref( i ) ); // 'g<void(int &r),reference_wrapper<int>>' is instantiated // then 'i' will be modified. std::cout << i << std::endl; // Output -> 1 } 103
  • 104. Polymorphic wrappers for function objects  Polymorphic wrappers for function objects are similar to function pointers in semantics and syntax, but are less tightly bound and can refer to anything which can be called (function pointers, member function pointers, or functors) whose arguments are compatible with those of the wrapper.  The template class function was defined inside the header <functional>, without needing any change to the C++ language. 104
  • 105. #include <functional> #include <iostream> struct Foo { Foo( int num ) : num_( num ) {} void print_add( int i ) { std::cout << num_ + i << 'n'; } int num_; }; void print_num( int i ) { std::cout << i << 'n'; } struct PrintNum { void operator()( int i ) const { std::cout << i << 'n'; } }; 105
  • 106. int main() { // store a free function std::function<void( int )> f_display = print_num; f_display( -9 ); // store a lambda std::function<void()> f_display_42 = []() { print_num( 42 ); }; f_display_42(); // store a call to a member function using namespace std::placeholders; const Foo foo( 314159 ); std::function<void( int )> f_add_display = std::bind( &Foo::print_add, foo, _1 ); f_add_display( 1 ); // store a call to a function object std::function<void( int )> f_display_obj = PrintNum(); f_display_obj( 18 ); } 106
  • 107. Type traits for metaprogramming  Metaprogramming consists of creating a program that creates or modifies another program (or itself). This can happen during compilation or during execution. 107
  • 108. template<int B, int N> struct Pow { // recursive call and recombination. enum{ value = B*Pow<B, N-1>::value }; }; template< int B > struct Pow<B, 0> { // ''N == 0'' condition of termination. enum{ value = 1 }; }; int quartic_of_three = Pow<3, 4>::value; 108
  • 109. type traits  Many algorithms can operate on different types of data; C++'s templates support generic programming and make code more compact and useful.  Nevertheless it is common for algorithms to need information on the data types being used. This information can be extracted during instantiation of a template class using type traits.  Type traits can identify the category of an object and all the characteristics of a class.  They are defined in the new header <type_traits>. 109
  • 110. // First way of operating. template< bool B > struct Algorithm { template<class T> static int do_it( T& a ) { printf( "firstrn" ); return 0; } }; // Second way of operating. template<> struct Algorithm<true> { template<class T> static int do_it( T a ) { printf( "secondrn" ); return 0; } }; 110 // Instantiating 'elaborate' will automatically // instantiate the correct way to operate. template<class T> int elaborate( T a ) { return Algorithm<std::is_floating_point<T>::value>::do_it( a ); } void main() { elaborate( 1.0f ); // second elaborate( 1 ); // first }

Notes de l'éditeur

  1. This type is easily determined procedurally by the compiler as part of its semantic analysis duties, but is not easy for the user to determine upon inspection.
  2. This will cause total to be stored as a reference, but value will be stored as a copy. The capture of this is special. It can only be captured by value, not by reference. this can only be captured if the closest enclosing function is a non-static member function.