Other C++11/14/17 features ● C++11 – Auto, decltype – Range for – Enum class – Initializer list – Default and delete functions – User defined literals ● C++17 – Structured binding – Nested namespaces – Compile-time static if – Attributes Zoltán Porkoláb: C++11/14 1
Auto, decltype void f(T&& t) { auto a = t; // type deduction const auto& car = t; // type deduction + modifiers auto&& pf = t; // universal reference auto i = 1; // int decltype(auto) j = i; // int decltype(i) decltype(auto) k = (i); // int& decltype((i)) } void g() { auto i = 1 , d = 3.14; // error, deduced types must match auto i = 1 , *p = &i; // ok, deduced type is int } template <typename F, typename... Args> // perfect forwarding requires decltype(auto) decltype(auto) forwarding( F fun, Args&&... args) { return fun(std::forward<Args>(args)... ); } template <auto n> // since C++17 auto f() -> std::pair<decltype(n), decltype(n)> // auto can't deduce from { init-list } { return { n, n}; } Zoltán Porkoláb: C++11/14 2
Range for void f(const vector<double>& v) { for (auto x : v) cout << x << '\n'; for (auto& x : v) ++x; // using reference allows us to change value } // You can read that as "for all x in v" going through starting with // v.begin() and iterating to v.end(). Another example: for (const auto x : { 1,2,3,5,8,13,21,34 }) cout << x << '\n'; // The begin() (and end()) can be a member to be called v.begin() // or a free-standing function to be called begin(v). Zoltán Porkoláb: C++11/14 3
Enum classes (C++11) enum Alert { green, yellow, election, red }; // traditional enum enum class Color { red, blue }; // scoped and strongly typed enum // no export of enumerator names into enclosing scope // no implicit conversion to int enum class TrafficLight { red, yellow, green }; Alert a = 7; // error (as ever in C++) Alert a1 = static_cast<Alert>(i); // ok, if i in 0..3 Color c = 7; // error: no int->Color conversion Color c1 = Color::blue; // ok int i2 = red; // ok: Alert->int conversion int i3 = Alert::red; // error in C++98; ok in C++0x int i4 = blue; // error: blue not in scope int i5 = Color::blue; // error: not Color->int conversion int i6 = static_cast<int>(Color::blue) // ok, 1 enum class Color : char { red, blue, }; // compact representation, C++11 allows extra , enum struct TrafficLight { red, yellow, green };// by default, the underlying type is int enum E { E1 = 1, E2 = 2, Ebig = 0xFFFFFFF0U }; // how big is an E? enum class EE : unsigned long { EE1 = 1, EE2 = 2, EEbig = 0xFFFFFFF0U }; // we are specific enum class Color_code : char; // (forward) declaration void foobar(Color_code* p); // use of forward declaration enum class Color_code : char { red, yellow, green, blue }; // definition Zoltán Porkoláb: C++11/14 4
Initializer list vector<double> v = { 1, 2, 3.456, 99.99 }; list<pair<string,string>> languages = { {"Nygaard","Simula"}, {"Richards","BCPL"}, {"Ritchie","C"} }; map<vector<string>,vector<int>> years = { { {"Maurice","Vincent","Wilkes"},{1913, 1945, 1951, 1967, 2000} }, { {"Martin","Ritchards"}, {1982, 2003, 2007} }, { {"David","John","Wheeler"}, {1927, 1947, 1951, 2004} } }; auto x1 = 5; // deduced type is int auto x2(5); // deduced type is int auto x3{ 5 }; // deduced type is int since C++17 auto x4 = { 5 };// deduced type is std::initializer_list Zoltán Porkoláb: C++11/14 5
Default and delete functions struct X { // ... X& operator=(const X&) = delete; // disallow copying X(const X&) = delete; // delete must be at the first declaration }; // Conversely, we can also say explicitly that // we want to default copy behavior: struct Y { // ... Y& operator=(const Y&&) = default; // default move semantics Y(const Y&&) = default; }; const char *func() { // static const char __fun__ = “func”; return __fun__; } Zoltán Porkoláb: C++11/14 6
User defined literals void f() { int i = 12, j = 014, k = 0xC, l = 0b1100; // literals complex<double> cd = 2 + 3i; // looking for operator"" I (also if, il) auto dur = 3h+5min+25s+567ms+765us+10ns; // chrono duration "Hello"s // basic_string, since C++14 "Hello"sv // string_view, since C++17 } // identifiers not starting with underscore are reserved for std:: constexpr complex<double> operator "" i(long double d) // imaginary literal { return {0,d}; // complex is a literal type } long double operator "" _w(long double); std::string operator "" _w(const char16_t*, size_t); unsigned int operator "" _w(const char*); void g() { 1.2_w // operator"" _w(1.2) u"one"_w // operator"" _w(u"one", 3) 12_w // operator"" _w("12") } Zoltán Porkoláb: C++11/14 7
Using (C++11) ● Typedef won't work well with templates ● Using introduce type alias using myint = int; template <class T> using ptr_t = T*; void f(int) { } // void f(myint) { } syntax error: redeclaration of f(int) // make mystring one parameter template template <class CharT> using mystring = std::basic_string<CharT,std::char_traits<CharT>>; Zoltán Porkoláb: C++11/14 8
Structured bindings (C++17) # include <tuple> // C++11 tuple auto get() // C++14 return type deduction { return std::make_tuple(“hello”,42); } int f1() { auto t = get(); // t is a tuple std::cout << std::get<1>(t); // 42 } int f2() { std::string s; int i; std::tie(s,i) = get(); // C++11 std::cout << s << i; } Zoltán Porkoláb: C++11/14 9
Structured bindings int f3() // C++17 { auto [fraction, reminder] = divide_reminder(16,3); // C++17 std::cout << “16/3 == ” << fraction << “, reminder is “ << reminder; } int f4() // C++17 { auto t = std:make_tuple(“hello”, 42); auto& [s, i] = t; ++i; std::cout << s << i; // “hello” 43 std::cout << std::get<0>(t) << “ “ << std::get<1>(t); // “hello” 43 } struct C { std::string name; int nstuds; }; int f4() // C++17 { C m{“Multiparadigm prog”, 55}; std::array<int, 5> arr{1,2,3,4,5}; auto [s, n] = m; auto [i1,i2,i3,i4,i5] = arr; } Zoltán Porkoláb: C++11/14 10
Structured bindings std::map<std::string, std::string> phone_book { {“abel”, “+36 30 123 4567”}, {“bela”, “+36 30 234 5678”}, ... } int f5() // C++17 { for ( const auto &[person, phone] : phone_book) { std::cout << “person ” << person << “, phone “ << phone << '\n'; } } Zoltán Porkoláb: C++11/14 11
Class template deduction (C++17) The compiler can deduce template parameter(s) from ● – Declaration that specifies initialization – New expression – Function-style cast expressions // examples from cppreference.com std::pair p(2,4.5) // C++11: std::pair<int,double>(2,4.5) std::vector v = { 1, 2, 3, 4}; // std::vetor<int> template <class T> struct A { A(T,T); }; auto y = new A{1,2}; // A<int>{1,2} std::mutex mtx; auto lck = std::lock_guard(mtx); // std::lock_guard<std::mutex>(mtx) std::copy_n(v1,3,std::back_insert_iterator(v2)); // back_inserter(v2) Zoltán Porkoláb: C++11/14 12
Class template deduction (C++17) Automatic and User defined deduction guideline ● // example from cppreference.com template <class T> struct Container { Container(T t) {} template<class It> Container(It beg, It end); }; template<class It> Container(It beg, It end) -> Container<typename std::iterator_traits<It>::value_type>; int main() { Container c(7) // ok T=int, using automatic guide std::vector<double> vd = { 3.14, 4.14, 5.14 }; auto c = Container(v.begin(), v.end()); // ok, T=double using guide Container d = {5,6}; // error } Zoltán Porkoláb: C++11/14 13
Attributes (C++11) Extra information helping the compiler or static analysis tools or others ● – Like OpenMP Earlier non standard, compiler dependent ● Compiler ignores unknown attributes (since C++17) ● #pragma once void fatal() __attribute__ ((noreturn)); struct S { char t[3]; } __attribute__ ((aligned (8))); #if COMPILING_DLL #define DLLEXPORT __declspec(dllexport) #else #define DLLEXPORT __declspec(dllimport) #endif Zoltán Porkoláb: C++11/14 14
Attributes From C++11 ● Almost everything can be annotated ● Type – Function – Enum – ... – [[attr]] [[namespace::attr]] // C++11 [[noreturn]] void terminate() noexcept; [[carries_dependency]] // C++14 [[depricated]] [[depricated(“reason”)]] Zoltán Porkoláb: C++11/14 15
Recommend
More recommend