最近、フィンランドのオウルで、標準化C ++に関する国際ワーキンググループ
WG21の会議が終了し、
Yandexの従業員が初めて
正式に参加しました。 多くの新しいクラス、メソッド、および言語の有用な革新を備えたC ++ 17の
ドラフトバージョンを承認しました。

旅行中、私たちは
Bjarne Stroustrupと昼食を
とり 、
Herb Sutterとエレベーターに乗って、
Beman Davesと握手し、
Vincent Botheと「空気を
吸う 」ために出かけ、
Gor Nishanovとオンラインゲームについて話し合い、Oulu市庁舎でレセプションを行い、市長と話しました。 また、新しいC ++標準で午前8時30分から午後5時30分まで全員と一緒に作業し、午後8時に集まり、さらに4時間働いて、いくつかの良いことを追加しました。
これで、新しい標準の「利点」を共有できます。 マルチスレッドアルゴリズム、新しいコンテナ、古いコンテナの珍しい機能、すばらしい新しいC ++の「構文糖」を見たいと思う人は誰でも、猫をお願いします。
if constexpr( 条件 )
C ++ 17では、コンパイル段階で次の場合に実行できるようになりました。
template <std::size_t I, class F, class S>
auto rget(const std::pair<F, S>& p) {
if constexpr (I == 0) {
return p.second;
} else {
return p.first;
}
}
. , :
- rget<0>( std::pair<char*, short>{} ) short;
- rget<1>( std::pair<char*, short>{} ) char*.
T& container::emplace_back(Args&&...)
emplace_back(Args&&...) sequence :
// C++11
some_vector.emplace_back();
some_vector.back().do_something();
// C++17
some_vector.emplace_back().do_something();
std::variant<T...>
: std::variant<T...> — union, .
std::variant<int, std::string> v;
v = "Hello word";
assert(std::get<std::string>(v) == "Hello word");
v = 17 * 42;
assert(std::get<0>(v) == 17 * 42);
boost::variant, :
- std::variant ;
- std::variant constexpr, constexpr ;
- std::variant emplace;
- — ;
- std::variant boost::static_visitor;
- std::variant ( `boost::make_recursive_variant<int, std::vector< boost::recursive_variant_ >>::type` ).
, ExecutionPolicy. , , :
std::vector<int> v;
v.reserve(100500 * 1024);
some_function_that_fills_vector(v);
//
std::sort(std::execution::par, v.begin(), v.end());
: , ExecutionPolicy, , std::terminate():
std::sort(std::execution::par, v.begin(), v.end(), [](auto left, auto right) {
if (left==right)
throw std::logic_error("Equal values are not expected"); // std::terminate()
return left < right;
});
. push pop():
// C++11
void push(std::multiset<value_type>&& items) {
std::unique_lock<std::mutex> lock(values_mutex_);
for (auto&& val : items) {
// ,
values_.insert(val);
}
cond_.notify_one();
}
value_type pop() {
std::unique_lock<std::mutex> lock(values_mutex_);
while (values_.empty()) {
cond_.wait(lock);
}
// ,
value_type ret = *values_.begin();
//
values_.erase(values_.begin());
return ret;
}
| // C++17
void push(std::multiset<value_type>&& items) {
std::unique_lock<std::mutex> lock(values_mutex_);
// , .
// (. #2)
values_.merge(std::move(items));
cond_.notify_one();
}
value_type pop() {
std::unique_lock<std::mutex> lock(values_mutex_);
while (values_.empty()) {
cond_.wait(lock);
}
// (. #2)
auto node = values_.extract(values_.begin());
lock.unlock();
// multiset'
return std::move(node.value());
}
|
C++17 , . pop() :
// rbtree '' (tree-node)
auto node = values_.extract(values_.begin());
// values_ , node
// values_mutex_ values_.
// , .
lock.unlock();
// , . std::move .
return std::move(node.value());
//
C++17 :
C++17 . , , , :
| |
---|
std::pair<int, double> p(17, 42.0);
| std::pair p(17, 42.0);
|
std::lock_guard<std::shared_timed_mutex> lck(mut_);
| std::lock_guard lck(mut_);
|
std::lock_guard<std::shared_timed_mutex> lck(mut_);
| auto lck = std::lock_guard(mut_);
|
std::string_view
C++17. C++11 , :
// C++11
#include <string>
void get_vendor_from_id(const std::string& id) { // , std::string
std::cout <<
id.substr(0, id.find_last_of(':')); //
}
// TODO: get_vendor_from_id(const char* id)
C++17 :
// C++17
#include <string_view>
void get_vendor_from_id(std::string_view id) { // , `const char*`, `char*`, `const std::string&` ..
std::cout <<
id.substr(0, id.find_last_of(':')); //
}
std::basic_string_view std::string_view — , , . Boost, boost::basic_string_ref boost::string_ref.
std::string_view C++17, std::string. <string_view> <string>, std::string_view .
:
- , string_view, , const std::string&, const char* ..;
- string_view ( `const string_view& id`, `string_view id`).
: string_view , , , '\0', string_view::data() , - .
if (init; condition)
:
// C++11
void foo() {
// ...
{
std::lock_guard<std::mutex> lock(m);
if (!container.empty()) {
// do something
}
}
// ...
}
, . C++17 :
// C++17
void foo() {
// ...
if (std::lock_guard lock(m); !container.empty()) {
// do something
}
// ...
}
lock if.
Structured bindings
std::set<int> s;
// ...
auto [it, ok] = s.insert(42);
// it — ; ok - bool .
if (!ok) {
throw std::logic_error("42 is already in set");
}
s.insert(it, 43);
// ...
Structured bindings std::pair std::tuple, :
struct my_struct { std::string s; int i; };
my_struct my_function();
// ...
auto [str, integer] = my_function();
...
C++17 :
- template <auto I> struct my_class{ /*… */ };
- filesystem — ;
- std::to_chars/std::from_chars — C ;
- std::has_unique_object_representations <T> — type_trait, «-» ;
- new alignment , ;
- inline — , ( inline );
- std::not_fn operator() const&, operator() && ..;
- . , , =, , — ;
- copy elision;
- ;
- std::string::data(), char* (!);
- constexpr , std::array ( :);
- std::iterator, std::is_literal_type, std::allocator<void>, std::get_temporary_buffer .. deprecated;
- , std::function;
- std::any — ;
- std::optional — , , , ;
- fallthrough, nodiscard, maybe_unused;
- constexpr ;
- [*this]( /*… */ ){ /*… */ };
- — type-erased , , ;
- lock_guard, ;
- .
C++Siberia ++ , , , , .