6.4 KiB
6.4 KiB
Nested namespace definitions
You can nest namespaces like this:
namespace A::B::C {
...
}
Instead of this:
namespace A {
namespace B {
namespace C {
...
}
}
}
Class template argument deduction
From C++17 class template arguments can be deduced automatically. Automatic template argument deduction was available earlier only for template functions.
std::pair p(1, 'x'); // C++17: OK, C++14: error: missing.
// std::pair<int, char>
std::pair<int, std::string> p(1, "x"); // C++14: OK
// std::pair<int, std::string>
auto p2 = std::make_pair(1, "x"); // C++17: OK, C++14: OK (but not string!)
// std::pair<int, const char*>
std::pair p3(1, "x"); // C++17: OK (but not string!), C++14 error
Selection statements with initializer (1)
New versions of the if and switch statements for C++:
if (init; condition)
status_code foo() { // C++14
{ //variable c scope
status_code c = bar();
if (c != SUCCESS) {
return c;
}
}
// ...
}
status_code foo() { // C++17
if (status_code c = bar(); c != SUCCESS) {
return c;
}
// ...
}
Selection statements with initializer (2)
switch (init; condition)
class Foo {
public:
enum class ErrorCode {
Ok,
Bad,
VeryBad
};
ErrorCode doSth() {}
}
int main() {
switch (Foo foo ; const auto err = foo.doSth()) {
case ErrorCode::Ok:
break;
case ErrorCode::Bad:
break;
case ErrorCode::VeryBad:
break;
}
}
Selection statements with initializer (3)
class ThreadSafeQueue {
public:
std::optional<int> try_pop() {
int val = 0;
// Lock guard is visible inside if-else
if (std::lock_guard lock(m_) ; queue_.empty()) {
return {};
} else {
val = queue_.front();
queue_.pop();
}
// Here mutex is no longer locked
logger << "pop value from queue";
return val;
}
private:
std::queue<int> queue_;
std::mutex m_;
};
Hiding variable inside if-else statement (2)
We can avoid assigning iterators and then comapre it in if statement. Now we can write it faster
int main() {
std::vector<int> vec;
if (const auto it = std::find(std::cbegin(vec), std::cend(vec), 10) ; it != std::cend(vec)) {
// *it* is visible here
} else {
// and here
}
// but not here
std::map<std::string, int>
if (const auto it = map.find("Ala") ; it != std::cend(map)) {
// ...
} else {
// ...
}
}
Unified initialization
-
C++11 introduce
{}for initialization -
C++17 fixed some problems with
{}and unified it.
Unified initialization C++11
- Guess output (compiler 4.7.4 with C++11 flag)
auto a {1}; //std::initializer_list<int>
auto b = {1}; //std::initializer_list<int>
auto c {1, 2}; //std::initializer_list<int>
auto d = {1, 2}; //std::initializer_list<int>
auto e = {1, 2, 3.f}; //Not compile
auto f {1, 2, 3.f} //Not compile
Unified initialization C++17
- Guess output (compiler 8.4 with C++17 flag)
auto a {1}; //int
auto b = {1}; //std::initializer_list<int>
auto c {1, 2}; //Not compile (mising =)
auto d = {1, 2}; //std::initializer_list<int>
auto e = {1, 2, 3.f}; //Not compile
auto f {1, 2, 3.f} //Not compile
Structural biding
- Unpack strucures, classes, tuples, pairs etc...
struct Foo{};
std::tuple<int, std::string, Foo> getTuple() {
return {5, "Ala has a cat", Foo{}};
}
struct Bar {
std::string str_;
double val_;
char c_;
std::vector<int> vec_;
};
int main() {
const auto& [id, topic, foo] = getTuple();
std::vector<Bar> bar;
for (const auto& [name, value, sign, vec] : bar) {
// ...
}
std::map<int, std::string> map;
for (const auto& [key, value] : map) {
// ..
}
};