C++17 So Far

Erich Keane

Software Engineer, iCDG, Intel

Erich.Keane@verizon.net

N3928: Extending Static Assert

  • static_assert no longer requires a message parameter
  • Previously was: static_assert(cond, msg);
  • Many did: #define BOOST_STATIC_ASSERT(B) static_assert(B, #B)
  • New static_assert version (in addition): static_assert(cond);

 

N3981: Trigraphs finally gone!

  • Digraphs still around, so beware!
  • Existed to support keyboards/character sets without brackets/braces
  • Trigraphs deprecated in C++11, removal in C++17
  • Were disabled by default in most compilers anyway
??= #
??( [
??/ \
??) ]
??' ^
??< {
??! |
??> }
??- ~

N4051: Allow typename in template template parameter

  • template templates (see last presentation!) had the sole case of requiring 'class' vs typename

 

template<template<typename, typename> class T, typename IT, typename Alloc>
//                                    ^^^^^ Only place in templates where 
//                                          class/template not interchangable
void DoThingToVector(T<IT, Alloc> vect)
{
    std::cout << typeid(IT).name() <<std::endl;
}

//Now This is allowable:
template<template<typename, typename> typename T, typename IT, typename Alloc>
//                                    ^^^^^ 
void DoThingToVector(T<IT, Alloc> vect)
{
    std::cout << typeid(IT).name() <<std::endl;
}

N3922: New Rules for auto deduction from braced-init-list

  • Auto-type deduction confusing with uniform initialization syntax and initializer lists:

 

 

  • Single item braced initialization: deduced from that entry
  • Multiple elements: auto deduction ill formed

 

auto x = foo(); // copy init
auto x{bar}; // direct initialization, is initializer_list!
int x = foo() // copy-initialization
int x{bar}; // direct-initialization
auto x1 = {1, 2}; // x1 is std::initializer_list<int>
auto x2 = {1, 2.0}; // error, not a init-list type
auto x3{1, 2}; // error, not a single argument (used to be init-list)
auto x4 = {3}; // x4 is std::initializer_list<int>
auto x5 {3}; // x5 is int, used to be init-list

N4259: Wording for std::uncaught_exceptions

  • Adds std::uncaught_exceptions, deprecates std::uncaught_exception
  •  

 

// Deprecated, returns whether an 
// uncaught exception exists:
bool uncaught_exception() noexcept;
// New, returns COUNT of uncaught exceptions
int uncaught_exceptions() noexcept;
// Example:
void error_handler(){
    try{
        do_stuff();
    }
    catch(...)
    {
        // true, but no way to detect how deep!
        uncaught_exception();
        // number of exceptions deep
        uncaught_exceptions(); 
        error_handler(); // :)
    }
}
int main(){
    try{
    do_thing();
    }
    catch(...)
    {
        uncaught_exception(); // true
        uncaught_exceptions(); // 1
        error_handler();
    }
}

N4266: Attributes for namespaces and enumerators

  • Allows the list of attributes to be attached to namespaces, clarifies enum usages
// OPT           OPT
inline namespace attributes_list name {...}
  • Attributes are compiler defined(in addition to standard ones) and standardizes the __attribute_((...)), __declspec(), etc mess
[[noreturn]] // function doesn't return, see std::abort
[[carries_dependency]] // continues std::memory_order dependency chain
[[deprecated]] [[deprecated("just because!")]] // deprecates function
[[fallthrough]] // For a switch, indicates case fall through is intentional
[[nodiscard]] // Issue warning if return value isn't used
[[maybe_unused]] // unused warning is suppressed

N4267: Adding u8 character literals

  • Allows character literals (single-quote chars, such as 'E') to be specified to be u8 in addition to u, U, or L, which is UTF-8
  • ONLY works if it is representable with a single UTF-8 code unit
  • Convertible (though narrow is undefined) to any char type
Prefix Type
u char16_t
U char32_t
L wchar_t
u8 UTF-8

N4295: Fold Expressions

  • Allows fold operations on Parameter Packs (variadic Template parameters) using base operators (+ - * / % ^ & | = < > << >> += -= *= /= %= ^= &= |= <<= >>= == != <= >= && || , .* ->*)

 

//Right Fold: (pack op ...) AKA Unary Right Fold
template <typename ...Args>auto sum(Args... args){ return (args + ...);}

// Left Fold: (... op pack) AKA Unary Left Fold
template <typename ...Args>auto mod_things(Args... args){return (... % args);}

// Right Accumulation fold: (pack op ... op init) AKA Binary Right Fold
template <typename T, typename ...Args>auto str_acc(T init, Args... args){return (args + ... + init);}

// Left accumulation fold: (init op ... op pack) AKA Binary Left Fold
template <typename ...Args>bool bool_accum(bool init, Args... args){return (init && ... && init);}

int main()
{
    sum(1,2,3,4,5);
    // expansion is:1 + (2 + (3 + (4 + (5))

    mod_things(2,3,4,5);
    // expansion is:((2 % 3) % 4) % 5

    str_acc(std::string("a"), "def", "ghi", "jkl");
    // expansion is:"def" + ("ghi" + ("jkl" + "a"))

    bool_accum(true, false, true, false, true);
    // expansion is:(((init && false[1]) && true[2]) && false[3]) && true[4]
}

N4279: Improved insertion interface for unique-key maps

  • Adds 2 new insertion methods to std::map and std::unordered_map
  • try_emplace: If key exists do not insert, do not modify args
    • insert/emplace both steal argument
  • insert_or_assign: inserts element or assigns if key exists

 

template <class ...Args>
pair<iterator, bool> try_emplace(const key_type&, Args&&...);
template <class ...Args>
pair<iterator, bool> try_emplace(key_type&, Args&&...);
template <class ...Args>
iterator try_emplace(const_iterator hint, const key_type&, Args&&...);
template <class ...Args>
iterator try_emplace(const_iterator hint, key_type&, Args&&...);

template <class M> 
pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
template <class M>
pair<iterator, bool> insert_or_assign(key_type& k, M&& obj);
template <class M> 
iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
template <class M>
iterator insert_or_assign(const_iterator hint, key_type& k, M&& obj);

N4280: Non-member size() and more

  • Uniform container access for size, empty, data
  • Most useful for template functions, specialization for C fixed size arrays are now usable the same as vector!

 

//Partial List, specializations for fixed size arrays.
// Data also has non-const c and initializer list
// returns c.size
template<class C> constexpr auto size(const C& c)->decltype(c.size());
// returns c.empty
template<class C> constexpr auto empty(const C& c)->decltype(c.empty());
// returns c.data
template <class C> constexpr auto data(const C& c)->decltype(c.data());

// All of the following are legal and uniform:
vector<int> v{...};
int arr[] ={...};

if (std::size(v) == std::size(arr))
    // Do a thing!

N4284: Contiguous Iterator

  • Extension of random-access-iterator type that is used when the container guarantees contiguous data storage, such as vector, string, valarray, array
  • Permits better specialization for <algorithm> support.  Also useful for parallelized algorithms

 

N4190: Removing auto_ptr, random_shuffle(), and Old<functional> stuff

  • A bunch of deprecated stuff is going away!
  • unary_function/binary_function/ptr_fun/mem_fun/mem_fun_ref
    • replaced by perfect forwarding/decltype/etc, function pointers being accessable elsewhere, and mem_fn
  • bind1st/bind2nd: replaced by bind
  • auto_ptr: replaced by unique_ptr
  • random_shuffle: replaced by shuffle, which uses better random source (not rand!)

 

N3505: Filesystem Library Proposal

  • Boost::filesystem based library for system file access!
  • Add UTF-8 support, codecvt and locale to boost::filesystem, otherwise extremely similar
  • In <filesystem>, class concepts:
    • file
      • directory, hard link, symbolic link, regular file
    • file name
    • path
      • absolute path, canonical path, relative path
  • Various functions that get paths, create sym/hard links, copy files, check file existence, permission access, file rename, disk space check, etc

 

P0024R2: The Parallelism TS Should be Standardized

  • Adds execution policies to a bunch of existing algorithms such as std::for_each
  • sequential_execution_policy (std::sequential): No threading, executed 1 at a time
  • parallel_execution_policy: (std::par): algorithm can be parallelized, may be invoked in different threads
  • parallel_vector_execution_policy(std::par_vec): same as parallel, but permits unordered, and unsequenced (inside each thread).


P0220R1: Adopt Library Fundamentals V1 TS Components for C++17

  • Most of the Library Tech Specifications were brought into the main libraries, including:
    • tuple apply
    • various Function object 'searchers'
    • optional and any
    • string_view

  

Q&A

Erich.Keane@verizon.net

Made with Slides.com