рд╕реА ++ рдПрдХ рдЬрдЯрд┐рд▓ рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рднрд╛рд╖рд╛ рд╣реИ, рдЖрдк рдЗрд╕рдореЗрдВ рд▓рдЧрднрдЧ рдкреВрд░реЗ рдЬреАрд╡рди рд╕реБрдзрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдХреБрдЫ рдмрд┐рдВрджреБ рдкрд░, рдореИрдВ рдЗрд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдЕрдзреНрдпрдпрди рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛: рднрд╛рд╖рд╛ рдХреЗ рдХреБрдЫ рдкрд╣рд▓реВ, рд╕рдВрднрд╡рддрдГ рдХрд╛рдлреА рд╕рдВрдХреАрд░реНрдг, рдФрд░ рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдФрд░ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░реЗрдВред рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реНрдХреЙрдЯ рдореЗрдпрд░реНрд╕, рд╣рд░реНрдм рд╕рдЯрд░ рдФрд░ рд╕реНрдЯреАрдлрди рдбреЗрд╣рд░реНрд╕реНрдЯ рдХреА рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рдкреБрд╕реНрддрдХреЛрдВ рд╕реЗ рдХрд╛рдлреА рд╣рдж рддрдХ рдкреНрд░реЗрд░рд┐рдд рдерд╛ред рдЬрдм рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдорд╛рддреНрд░рд╛ рдореЗрдВ рд╕рд╛рдордЧреНрд░реА рдЬрдорд╛ рд╣реЛ рдЧрдИ рдереА, рддреЛ рдореИрдВрдиреЗ рдЙрдирдХреЗ рд▓рд┐рдП рдЦрд╛рдмрд░реЛрд╡рдЪрди рд╢реБрд░реВ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рддреЛ рдпрд╣ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдереА, рдЬрд┐рд╕реЗ рдореИрдВрдиреЗ "рд╕реА ++" рдХрд╣рд╛, рдЧрд╣рд░рд╛рдИ рдореЗрдВ рдЦреБрджрд╛рдИред рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЛ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрднреА рднреА рд╢реБрд░реБрдЖрддреА рдкрд░ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдордзреНрдпрд╡рд░реНрддреА рд╕реНрддрд░ рдкрд░ рдХреЗрдВрджреНрд░рд┐рдд рд╣реИред рдкрд╣рд▓рд╛ рд╡рд┐рд╖рдп C ++ рдореЗрдВ рдУрд╡рд░рд▓реЛрдбрд┐рдВрдЧ рд╣реИред рд╡рд┐рд╖рдп рдмрд╣реБрдд рд╡реНрдпрд╛рдкрдХ рдирд┐рдХрд▓рд╛ рдФрд░ рд╣рдореЗрдВ рддреАрди рд▓реЗрдЦ рдорд┐рд▓реЗред рдкрд╣рд▓рд╛ рд▓реЗрдЦ рдУрд╡рд░рд▓реЛрдбрд┐рдВрдЧ рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ, рджреВрд╕рд░рд╛ рдУрд╡рд░рд▓реЛрдбрд┐рдВрдЧ рдСрдкрд░реЗрдЯрд░реЛрдВ рдФрд░ рддреАрд╕рд░рд╛ рдУрд╡рд░рд▓реЛрдбрд┐рдВрдЧ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИnew/delete
ред рддреЛ, рдЪрд▓реЛ рдЦреБрджрд╛рдИ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред
рд╡рд┐рд╖рдп - рд╕реВрдЪреА
рд╡рд┐рд╖рдп - рд╕реВрдЪреА рдкрд░рд┐рдЪрдп
рдПрдХ рд╡реНрдпрд╛рдкрдХ рдЕрд░реНрде рдореЗрдВ, рдУрд╡рд░рд▓реЛрдбрд┐рдВрдЧ рдПрдХ рд╣реА рдирд╛рдо рдХреЗ рд╕рд╛рде рдХрдИ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдПрдХ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред рдХрдВрдкрд╛рдЗрд▓рд░ рдЙрдиреНрд╣реЗрдВ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдЕрд▓рдЧ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЙрдирдХреЗ рдкрд╛рд╕ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдПрдХ рдЕрд▓рдЧ рд╕реЗрдЯ рд╣реИред рдХреЙрд▓ рдмрд┐рдВрджреБрдУрдВ рдкрд░, рдХрдВрдкрд╛рдЗрд▓рд░ рддрд░реНрдХреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддрд╛ рд╣реИ рдФрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕ рд╡рд┐рд╢реЗрд╖ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд╣рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рд░реВрд╕реА рднрд╛рд╖рд╛ рдХреЗ рд╕рд╛рд╣рд┐рддреНрдп рдореЗрдВ, "рд╕рд╛рдЭрд╛рдХрд░рдг" рд╢рдмреНрдж рдХреЛ рдХрднреА-рдХрднреА рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЬрдбрд╝ рдирд╣реАрдВ рд▓рд┐рдпрд╛ рд╣реИред
рдУрд╡рд░рд▓реЛрдбрд┐рдВрдЧ рдХрдИ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рд╣реИ, рд╣рдо рдХреЗрд╡рд▓ C ++ 17 рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред
1. рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рд╛рд╡рдзрд╛рди
1.1ред рдЕрддрд┐рднрд╛рд░рд┐рдд рдХрд╛рд░реНрдп
( ) (overloaded), (scope) . , (=delete
) .
void Foo();
char Foo();
void Foo(int x);
void Foo(int x) noexcept;
void Foo(double x);
void Foo(double) = delete;
, .
, . (decay) ,
void Foo(int x[4]);
void Foo(int x[]);
void Foo(int *x);
, .
.
, , const
( volatile
),
void Foo(int x);
void Foo(const int x);
, .
1.2.
. (lookup) , (candidate functions). (template argument deduction). ( ). , . , . , , , ┬л ┬╗ (match the arguments most closely). (overload resolution). , , (ambiguous call to overloaded function). :
void Foo(float x);
void Foo(double x);
Foo("meow")
, Foo(42)
, , Foo(3.14f)
Foo(3.14)
.
(overload resolution rules) ( , ), , . .
┬л ┬╗ : - . .
тАФ . ( private
protected
). ( =delete
). , . , , .
1.3.
, . . , . . , , , . () .
, . . , . , , . (hide) . , , , , , .
1.3.1.
, , . .
class X {};
X x;
x.Foo();
X::Foo(42);
X
. X
.
namespace N {}
N::Foo();
N
, .
::Foo();
, .
┬л┬╗ .
, , .
( ), , .
{
Foo();
}
. (, , . .) , ( -) .
1.3.2.
.
class B
{
public:
void Foo(int x);
};
class D : public B
{
public:
D();
void Foo(double x);
};
D d;
d.Foo(42);
Foo
, ? D::Foo(double)
, B::Foo(int)
. ( D
), , ( B
) . D::Foo(double)
. D::Foo(double)
, , B::Foo(int)
, . , D
Foo
, B
B::Foo(int)
.
. C++ , , . . , . ( , .)
1.3.3.
C++, . ( ), :
{
void Foo();
void Foo(int x);
Foo(42);
}
, , , C++ . , , , . , . ( ), ( - ) .
1.4.
using
- using
-. , , .
, , , , , .
1.4.1. using-
:
class B
{
public:
void Foo(int x);
};
class D : public B
{
public:
using B::Foo;
void Foo(double x);
};
D d;
d.Foo(42);
Foo
B
, B::Foo(int)
.
1.4.2. using-
using
- , . using
- . , , using
-, , . :
namespace N
{
void Foo(int x);
}
void Foo(const char* x);
void Test()
{
using N::Foo;
Foo(42);
Foo("meow");
}
, Foo
, using
- :
namespace N
{
void Foo(int x);
}
void Foo(const char* x);
using N::Foo;
void Test()
{
Foo(42);
Foo("meow");
}
1.4.3. using-
N
.
using namespace N;
using
-. N
N::
. N
, using
- (, using
-, ). , , using
- , .
, , , , . ( using
-.)
namespace
{
void Foo(int x);
}
void Foo(const char* x);
Foo(42);
Foo("meow");
1.4.4. ,
, . :
namespace N
{
class X {};
void Foo(const X& x);
}
( N
):
N::X x;
Foo(x);
N
, , N::Foo(const X&)
. , (argument depended lookup, ADL), . ADL , .
2.
, .
2.1. ┬л┬╗
C++ . , . , , . : , , .
bool
. bool
int
bool
. . bool
int
.
void Foo(int x);
void Foo(bool x);
int x = 6, y = 5;
Foo(x == y);
Foo(x = y);
void Foo(bool x, int y);
void Foo(int x, bool y);
, :
Foo(1, 2);
, . int
.
enum Qq { One = 1, Two };
void Foo(int x);
void Foo(Qq x);
Foo(One);
Foo(42);
, , int
long
.
void Foo(int x);
void Foo(long x);
Foo(42);
Foo(42L);
. . , , . :
void Foo(long x);
void Foo(long long x);
void Foo(float) = delete;
void Foo(double) = delete;
void Foo(long double) = delete;
2.2.
C++11 тАФ std::nullptr_t
nullptr
. .
void Foo(int x);
void Foo(void* x);
Foo(0);
Foo(nullptr);
C++98
Foo((void*)0);
. nullptr
, nullptr
.
void Foo(void* x);
void Foo(std::nullptr_t);
void* x = nullptr;
Foo(x);
Foo(nullptr);
.
2.3.
++11 (uniform initialization) тАФ std::intializer_list<>
. , , . . .
- тАФ
{}
, . , . - ,
std::intializer_list<>
. std::intializer_list<>
, , . , std::intializer_list<>
, ( ), .
std::vector<T>
, std::intializer_list<T>
.
:
std::vector<int> v1(3, 1), v2{3, 1};
v1
тАФ 3 1. v2
тАФ 2 3 1, std::intializer_list<int>
, , .
:
std::vector<const char*> u1(3, "meow"), u2{3, "meow"};
u1
u2
, 3. u2
std::intializer_list<const char*>
, u1
.
:
std::vector<bool> b1(3, true), b2{3, true};
b1
3 , true
. b2
, std::intializer_list<bool>
int
bool
.
[Meyers2].
2.4.
, ...
, , . .
2.5.
, , . тАФ c .
. ( , ), .
2.5.1.
. , . , . , .
, , . , . , , . [Sutter2].
C++11 (variadic templates). , , , .
2.5.2. SFINAE
, , . :
template<typename T>
void Foo(const T* x);
Foo(42);
, , , , , ┬л┬╗ . SFINAE, Substitution Failure is not an Error ( ).
2.5.3.
, .
void Foo(int x);
template<typename T>
void Foo(T x);
template<>
void Foo<double>(double x);
template<>
void Foo<const char*>(const char* x);
template<typename T>
void Foo(const T* x);
template<typename T>
class U {};
template<typename T>
void Foo(U<T> u);
, :
Foo(42);
Foo(3.14);
Foo(42L);
Foo("meow");
Foo(U<int>());
: 1 int
. .
, double
int
. : 1 double
1 double
, .
, long
int
. : 1 long
, .
, : 1 const char*
2 char
. 2 , , 1 const char*
.
, : 1 U<int>
3 int
. 3 .
2.5.4.
:
void Foo(int x);
template<typename T>
void Foo(T x);
int
, int&
, const int
, const int&
, (long
, short
, unsigned int
, etc.) . , (greedy). , , , . . , . тАФ (template disabling). :
template<
typename T,
typename S = std::enable_if_t<!std::is_integral<T>::value>>
void Foo(T x);
SFINAE , , .
, , , :
template<typename T>
void FooInt(T x);
template<typename T>
void FooEx(T x);
template<typename T>
void Foo(T x)
{
if constexpr (std::is_integral<T>::value)
{
FooInt(x);
}
else
{
FooEx(x);
}
}
template<typename T>
void Foo(T x)
{
std::is_integral<T>::value
? FooInt(x)
: FooEx(x);
}
<type_traits>
.
2.6. ┬л┬╗
┬л┬╗ : , , , rvalue .
. :
- lvalue тАФ ;
- () lvalue тАФ ;
- rvalue тАФ lvalue,
std::move();
- () rvalue тАФ .
тАФ .
, .
:
void Foo(T& x);
lvalue.
rvalue-:
void Foo(T&& x);
rvalue.
:
void Foo(const T& x);
void Foo(T x);
.
2.6.1. ,
:
void Foo(T& x);
void Foo(const T& x);
lvalue ( ), .
:
void Foo(T& x);
void Foo(T x);
rvalue , lvalue .
:
void Foo(const T& x);
void Foo(T x);
.
- const
this
.
class X
{
public:
X();
void Foo();
void Foo() const;
void DoSomething() const;
void DoSomethingElse();
};
void X::DoSomething() const
{
Foo();
}
void X::DoSomethingElse()
{
Foo();
}
X x;
x.Foo();
const X cx;
cx.Foo();
H - rvalue , rvalue. rvalue .
class X
{
public:
X();
void Swap(X& other) noexcept;
};
X x;
X().Swap(x);
x.Swap(X());
rvalue . , . rvalue . ( , rvalue .) rvalue . , , , , . [Sutter1].
2.6.2. Rvalue
C++11 . тАФ rvalue-. Rvalue- C++ , , rvalue-. , , ┬л┬╗ .
:
void Foo(T&& x);
void Foo(const T& x);
rvalue ( ), .
:
void Foo(T&& x);
void Foo(T x);
lvalue , rvalue , .
:
void Foo(T&& x);
void Foo(T& x);
rvalue , lvalue , .
, тАФ rvalue, тАФ , , . ( .) , , , .
++11, rvalue- тАФ -. (lvalue/rvalue) this
.
class X
{
public:
X();
void Foo() &;
void Foo() &&;
};
X x;
x.Foo ();
X().Foo();
: rvalue- lvalue. , rvalue-, lvalue , - , std::move()
, rvalue- .
2.6.3.
template<typename T>
void Foo(T&& x);
rvalue-, (universal reference). . lvalue x
T&
, const T&
, rvalue T&&
. x
lvalue, - std::forward<T>()
, , T&&
, rvalue. (greedy), . , 2.5. (perfect forwarding) . [Meyers2].
3. ,
3.1.
C++ , - (, , , ), . (incomplete declaration), (forward declaration). . .
class X;
class Y;
void Foo(X* x);
void Foo(Y* y);
X* px;
Foo(px);
X
, .
3.2.
.
void Foo(int x);
void Foo(const char* x);
void (*pF)(int) = Foo;
, . (, ) , ADL .
namespace N
{
class X {};
void Foo(const X& x);
}
void (*pF)(const N::X&) = Foo;
void (*pF)(const N::X&) = N::Foo;
using N::Foo;
void (*pF)(const N::X&) = Foo;
.
void Foo(int x);
void Foo(const char* x);
auto pf = static_cast<void(*)(int)>(Foo);
ADL .
, auto
.
auto pf = Foo;
Foo
, , pf
Foo
. Foo
, , .
, (). std::function<>
, , , std::sort()
. .
- - .
class X
{
void Foo(int a);
void Foo(const char* a);
};
void (X::*pF)(int) = &X::Foo;
3.3.
.
void Foo(int x);
void Foo() { Foo(0); }
void Foo(int x = 0);
, Foo()
, . , .
void (*pF1)(int) = Foo;
void (*pF0)() = Foo;
.
, , .
3.4.
. , , , , , . (┬л┬╗ , . 1.3). [Dewhurst]. тАФ . , ( , - ), , . . , Visitor.
3.5.
, , тАФ , . , . , .
, . -, std::input_iterator_tag
. (typedef
) тАФ iterator_category
. , -, iterator_category
, , . :
void DisplayIterCat(std::input_iterator_tag tag)
{
std::cout << "Input iterator\n";
}
template<class Iter>
void DisplayIterCat(Iter it)
{
DisplayIterCat(typename Iter::iterator_category());
}
typename
. , iterator_category
Iter
.
C++ , , . :
template<typename T, T val>
struct integral_constant;
T
T
, , . :
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
, , .
, . :
sizeof(Foo(expr))
. expr
, . , Foo
, Foo
. .
C++17 if constexpr ()
, , . ( ) .
4.
тАФ , . , .
, . , . , .
, .
тАФ .
. Visitor
A
, V
void DoDblDispatchOper(A* a, V* v);
a
v
, , a
, v
, . . , , . Visitor тАФ [GoF].
, IAcceptor
IVisitor
.
class IVisitor;
class IAcceptor
{
public:
virtual void Accept(IVisitor* visitor) = 0;
};
class A1;
class A2;
class IVisitor
{
public:
virtual void Visit(A1* a) = 0;
virtual void Visit(A2* a) = 0;
};
class A1 : public IAcceptor
{
void Accept(IVisitor* visitor) override
{
visitor->Visit(this);
}
};
class A2 : public IAcceptor
{
void Accept(IVisitor* visitor) override
{
visitor->Visit(this);
}
};
class V1 : public IVisitor {};
class V2 : public IVisitor {};
IVisitor
Visit()
, IAcceptor
. Visit()
, .
void IAcceptor::Accept(IVisitor* visitor);
, :
visitor->Visit(this);
this
, Visit()
. Visit()
, visitor
.
void DoDblDispatchOper(IAcceptor* acceptor, IVisitor* visitor)
{
acceptor->Accept(visitor);
}
Voila. .
.
- . тАФ ( ) .
template<typename T>
void swap(T& a, T& b);
, , . . , std::swap()
, , . , std::swap()
, , , . , .
1. - Swap()
( ), .
class X
{
public:
void Swap(X& other) noexcept;
};
, , C++11 noexcept
.
2. , X
( , ), (-) swap()
( ):
inline void swap(X& a, X& b) noexcept { a.Swap(b); }
, ADL, std::swap()
.
3. std::swap()
X
namespace std
{
template<>
void swap<X>(X& a, X& b) noexcept { a.Swap(b); }
};
std
, - . std
.
, ? тАФ . , , .
namespace N
{
template<typename T>
T x, y;
swap(x, y);
, T
swap()
, , . std::swap()
, , .
:
std::swap(x, y);
swap()
std::swap()
тАФ . .
:
using std::swap;
swap(x, y);
, . std::swap()
, . std::swap()
. std::swap()
.
, ( std
)
std::swap(x, y);
swap(x, y);
[Meyers1] , .
, .
template<typename T>
class X
{
public:
void Swap(X& other) noexcept;
};
template<typename T>
void swap(X<T>& a, X<T>& b) noexcept { a.Swap(b); }
std::swap()
, std
, , , , .
friend
swap()
:
template<typename T>
class X
{
void Swap(X& other) noexcept;
friend void swap(X& a, X& b) noexcept { a.Swap(b); }
};
, - Swap()
.
[GoF]
., ., ., . - . .: . . тАФ .: , 2001.
[Dewhurst]
, . C++. .: . . тАФ .: , 2012.
[Meyers1]
, . C++. 55 .: . . тАФ .: , 2014.
[Meyers2]
, . C++: 42 C++11 C ++14.: . . тАФ .: ┬л.. ┬╗, 2016.
[Sutter1]
, . C++.: . . тАФ : ┬л.. ┬╗, 2015.
[рд╕рдЯрд░ реи]
рд╕рдЯрд░, рд╢рд╕реНрддреНрд░ рдХрд╛ рдХреЛрдЯред C ++ рдореЗрдВ рдирдП рдЬрдЯрд┐рд▓ рдХрд╛рд░реНрдп ред: рдкреНрд░рддрд┐ред рдЕрдВрдЧреНрд░реЗрдЬреА рд╕реЗ - рдПрдо: рдПрд▓рдПрд▓рд╕реА тАЬрдЖрдИ.рдбреА. рд╡рд┐рд▓рд┐рдпрдореНрд╕, 2015ред