2018/04/07 齋藤 昂也
用途: タプルを分解したい
C++17 以前:
std::tuple<int, double, std::string> f() {
return std::make_tuple(42, 3.14, "hello");
}
int main() {
int i;
double d;
std::string s;
std::tie(i, d, s) = f();
}
C++17:
std::tuple<int, double, std::string> f() {
return std::make_tuple(42, 3.14, "hello");
}
int main() {
auto [i, d, s] = f();
}
C++17 以前:
int main() {
std::map<std::string, int> m = {
{"a", 1},
{"b", 2}
};
for (auto& p : m) {
p.second *= 2;
}
for (const auto& p : m) {
std::cout << p.first << ": " << p.second << std::endl;
}
}
C++17:
int main() {
std::map<std::string, int> m = {
{"a", 1},
{"b", 2}
};
for (auto& [key, value] : m) {
value *= 2;
}
for (const auto& [key, value] : m) {
std::cout << key << ": " << value << std::endl;
}
}
if (int x = some_function(); x % 2 == 0) {
// do something...
}
switch (int x = some_function(); x) {
case 1:
// do something...
break;
}
// vec は std::vector<int> と推論される
std::vector vec = {1, 2, 3, 4, 5};
std::mutex m;
std::lock_guard gd(m); // std::lock_guard<std::mutex> と推論される
struct Foo {
// Fooはコピーもムーブもできない
Foo() = default;
Foo(const Foo&) = delete;
Foo(Foo&&) = delete;
};
Foo foo()
{
// オブジェクトを生成して、「そのまま」返す
return Foo();
}
auto y = foo(); // OK
C++17以前:
namespace A {
namespace B {
namespace C {
// A::B::C に属するものをここに書く
}
}
}
C++17:
namespace A::B::C {
// A::B::C に属するものをここに書く
}
値が入っているもしれないし、ないかもしれないクラス
std::optional<std::string> my_getline(std::istream& is) {
std::string line;
if (std::getline(is, line)) {
return std::move(line);
}
return std::nullopt;
}
int main() {
const auto line = my_getline(std::cin);
if (line) {
std::cout << *line << std::endl;
} else {
std::cout << "行を取得できませんでした。\n";
}
}
(コピーできるものなら)なんでも格納できるクラス
std::any x;
x = 42;
std::cout << std::any_cast<int>(x) << std::endl;
x = "hoge"s;
std::cout << std::any_cast<std::string>(x) << std::endl;
型安全 union
std::variant<int, std::string> v;
v = 42;
std::cout << std::get<int>(v) << std::endl;
v = "hoge"s;
std::cout << std::get<std::string>(v) << std::endl;
文字列への参照を統一的に扱うクラス
std::size_t count_a(std::string_view str) {
std::size_t count = 0;
for (char x : str) {
if (x == 'a') {
++count;
}
}
return count;
}
count_a("abcdefg"); // OK
std::string s = "aaa";
count_a(s); // OK
並列実行ポリシーを引数に渡すことで
std::vector v = {1, 2, 3, 4, 5};
std::atomic<int> sum{0};
std::for_each(std::execution::par, v.begin(), v.end(), [&] (int x) {
sum += x;
})
プラットホーム非依存のファイルシステムライブラリ
(例)カレントディレクトリのファイル一覧を表示:
using namespace std::filesystem;
path dir = current_path();
for (const auto& p : directory_iterator(dir)) {
std::cout << p << std::endl;
}
ご清聴ありがとうございました
ありがとうございました