Professional Documents
Culture Documents
{…}
{…}
{…}
• http://en.cppreference.com/w/cpp/language/constexpr
• http://en.cppreference.com/w/cpp/named_req/LiteralType
constexpr - példák
public:
template<std::size_t N>
constexpr conststr(const char(&a)[N]): p(a), sz(N - 1) {}
constexpr operator[](std::size_t n) const {
return n < sz ? p[n] : throw std::out_of_range("");
}
int main() {
Foo<int> f1 = getFoo<int>();
}
Move constructor
Foo<int> f; 5 3 12 11 4
Move constructor
Foo<int> f; 5 3 12 11 4 f
f1 = getFoo<int>(); f1
Move constructor
Foo<int> f; 5 3 12 11 4 f
f1 = getFoo<int>(); f1
Move constructor
Foo<int> f; 5 3 12 11 4 f
f1 = getFoo<int>(); f1
Move constructor
• Ha visszatérési értékként olyan változóba tároljuk, ami már létezik,
akkor az operator= fut le
• Létezik move operator= is
• Szintén jobbérték referenciát kap
• Ha van kifejtett másoló konstruktor, akkor a default move konstruktor
deleted
• Ha van kifejtett move konstruktor, akkor a default másoló konstruktor
deleted
• Az aktuális változó tartalmát fel kell szabadítani
Move constructor
Foo<T>& operator= (Foo<T> &&right) {
if (&right == this)
return *this;
delete [] tarolo;
tarolo = right.tarolo;
right.tarolo = nullptr;
akt_db = right.akt_db;
meret = right.meret;
return *this;
}
Lambda függvények
Függvény pointerek
• C-ben, C++-ban mindig is léteztek
bool foo(int a) {
return a < 0;
}
...
...
std::function<bool(int)> pf = &foo;
cout << pf(-4) << endl;
Lambda függvények és kifejezések
• C++11-ben létrehozhatunk névtelen függvényeket is (lambda
függvények)
• #include <functional>
Lambda függvények és kifejezések
capture-list
(később bővebben)
Lambda függvények és kifejezések
capture-list
(később bővebben) Paraméterei a lambda
függvénynek
Lambda függvények és kifejezések
capture-list
(később bővebben) Paraméterei a lambda
Visszatérési típus
függvénynek
Lambda függvények és kifejezések
Függvénytörzs
capture-list
(később bővebben) Paraméterei a lambda
Visszatérési típus
függvénynek
Lambda függvények és kifejezések
//Generikusan ugyanez
int a = 3, b = 5;
vector<int> c{ 2,3,5,6,7,1,2,3 };
[=]() {c[a] += b;};
Lambda függvények és kifejezések
int a = 3, b = 5;
vector<int> c{ 2,3,5,6,7,1,2,3 };
[=]() {c[a] += b;}; X
c must be modifiable lvalue.
Lambda függvények és kifejezések
• Mi történik?
int a = 3, b = 5;
vector<int> c{ 2,3,5,6,7,1,2,3 };
[&]() {c[a] += b;};
Lambda függvények és kifejezések
int a = 3, b = 5;
vector<int> c{ 2,3,5,6,7,1,2,3 };
[&]() {c[a] += b;}; OK
Lambda függvények és kifejezések
• Mi történik?
int a = 3, b = 5;
vector<int> c{ 2,3,5,6,7,1,2,3 };
[&a, b, c]() {b *= c[a];};
Lambda függvények és kifejezések
int a = 3, b = 5;
vector<int> c{ 2,3,5,6,7,1,2,3 };
[&a, b, c]() {b *= c[a];}; X b must be a modifiable lvalue
Lambda függvények és kifejezések
• Mi történik?
int a = 3, b = 5;
vector<int> c{ 2,3,5,6,7,1,2,3 };
[&a, &b, c]() {b *= c[a];}; OK
Lambda függvények és kifejezések
• Lambda függvények további lehetőségekkel bővültek
• Részletek: http://en.cppreference.com/w/cpp/language/lambda
Példa
#include <iostream>
#include <function>
int main() {
[out = std::ref(std::cout << "Hello")]() {out.get() <<
"World\n";}();
}
Multithreading
Bevezető
Multithreading
• Az std::thread osztály segítségével létrehozhatunk szálakat,
amiknek paraméterül megadjuk a végrehajtandó függvényt
• #include <thread>
thread t1(hello);
thread t2(bye, 5);
Multithreading
Fork-Join
• Először is, az előbbi kód hiányos…
main thread
main thread
main thread
main thread
void bye(int i) {
Mit ír ki? for(int j = 0; j < i; j++)
cout << j << endl;
}
thread t1(hello);
thread t2(bye, 5);
t1.join();
t2.join();
void hello() {
Multithreading cout << ”H” << endl;
cout << ”E” << endl;
cout << ”L” << endl;
cout << ”L” << endl;
cout << ”O” << endl;
}
void bye(int i) {
Mit ír ki? for(int j = 0; j < i; j++)
cout << j << endl;
Mind a két szál a cout-ra }
írogat, a kimenet attól
függ, hogy milyen gyorsan …
végeznek
thread t1(hello);
thread t2(bye, 5);
t1.join();
t2.join();
Ha túl sok a szál
• Elméletileg a programban akárhány szál lehet
• Fizikailag a processzor csak megadott számú szálat képes
párhuzamosan futtatni
• Ha ennél több szál van, akkor ezek között váltogatás, ütemezés
történik
unsigned int n = std::thread::hardware_concurrency();
std::cout << n << " concurrent threads are supported.\n";
Kölcsönös kizárás
• Ha egy változóhoz több szál hozzáfér, akkor át kell gondolni annak a
változónak a használatát
Kölcsönös kizárás
• Ha egy változóhoz több szál hozzáfér, akkor át kell gondolni annak a
változónak a használatát
void foo()
{
cout << ++A::a << endl;
}
int main()
{
thread t1(foo); t1.join();
thread t2(foo); t2.join();
thread t3(foo); t3.join();
}
class A
{
Mit ír ki?
public static int a;
}; 6
int A::a = 5;
7
void foo()
{ 8
cout << ++A::a << endl;
}
int main()
{
thread t1(foo); t1.join();
thread t2(foo); t2.join();
thread t3(foo); t3.join();
}
class A
{
Mit ír ki?
public static thread_local int a;
};
int A::a = 5;
void foo()
{
cout << ++A::a << endl;
}
int main()
{
thread t1(foo); t1.join();
thread t2(foo); t2.join();
thread t3(foo); t3.join();
}
class A
{
Mit ír ki?
public static thread_local int a;
}; 6
int A::a = 5; 6
void foo() 6
{
cout << ++A::a << endl;
}
int main()
{
thread t1(foo); t1.join();
thread t2(foo); t2.join();
thread t3(foo); t3.join();
}
Párhuzamosítás
• Megkülönböztetünk
• Adatpárhuzamosítást:
Az adatot szétosztjuk a szálak között a gyorsabb feldolgozás érdekében
• Számításpárhuzamosítást:
Az összetett műveletet szétszedjük részekre, minden szál a sajátját számolja ki
int foo = sqrt(bar) + sin(a) / arcsin(b);
Szál késleltetése
• C-ben is lehetett használni sleep(), usleep(), stb. függvényeket,
de ezek rendszerfüggőek
• C++11-ben van erre megfelelő megoldás a chrono névtér
használatával
• Azt a szálat altatja, amit meghívtunk
#include <chrono>
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::this_thread::sleep_for(std::chrono::seconds(2));
Gyakorló feladat
Gyakorló feladat
• Készítsünk el a DegToRad és RadToDeg függvényeket, amelyek a
szögek átváltását végzik fok és radián között (double értékek)