前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++17 New Features

C++17 New Features

作者头像
JIFF
发布2020-06-09 12:33:49
1K0
发布2020-06-09 12:33:49
举报
文章被收录于专栏:Toddler的笔记Toddler的笔记

笔者序

如果说 C++11 和 C++20 是两个改动大、影响比较深远的"大版本",那么我感觉 C++17 算是一个小版本。(推荐 vs2019,gcc8,clang10,支持 C++17)

C++17 这个版本让语法变的更自然,代码更容易读懂,会让人觉得:

C++ 本该如此

1.Structured Binding

Automatically decomposes packed structures like tuples structs and arrays into individual named variables.

代码语言:javascript
复制
auto [ a, b, c ] = tuple; // or struct or array

2.CTAD (Class template argument deduction)

Before C++17, template deduction worked for functions but not for classes.

代码语言:javascript
复制
std::pair p(2, 4.5);  // deduces to std::pair<int, double>
auto lock = std::lock_guard(mtx);  // deduces to std::lock_guard<std::mutex>

3.Init-statements for if and switch

new "if statement with initializer".

代码语言:javascript
复制
if (auto val = GetValue(); condition(val))
 // on success
else
 // on false...

val is only present in the scope of the if and the else clause.

4.constexpr if-statements

The static-if for C++!

Reduces the need to use SFINAE or tag dispatch.

代码语言:javascript
复制
if constexpr (is_floating_point_v<T>) { }

5.constexpr lambda expressions

constexpr can be used in the context of lambdas.

代码语言:javascript
复制
constexpr auto ID = [] (int n) {
  return n;
};
static_assert(ID(3) == 3);

6.Inline variables

With static variables you usually need to declare it in .h file and initialize it in some .cpp file.

in C++17, a variable could be declared inline. It has the same semantics as a function declared inline: it can be defined, identically, in multiple translation units, must be defined in every translation unit in which it is used, and the behavior of the program is as if there was exactly one variable.

Also, note that constexpr variables are inline implicitly.

代码语言:javascript
复制
struct MyClass {
  static inline/constexpr const int sValue = 777;
};

The advantage of inline over constexpr is that your initialization expression doesn't have to be constexpr.

7.Non-type template parameters with auto type

Automatically deduce type on non-type template parameters.

代码语言:javascript
复制
template<auto value>
void f() { }
f<10>(); // deduces int

8.Fold Expression

With C++11 we got variadic templates. But you had to write several different versions of a function (like one for one parameter, another for two or more parameters).

代码语言:javascript
复制
auto sum() {
    return 0;
}

template<typename T1, typename... T>
auto sum(T1 s, T... ts) {
    return s + sum(ts...);
}

And with C++17 we can write much simpler code:

代码语言:javascript
复制
template<typename... Args>
auto sum2(Args... args)  {
  return (args + ...);
}
  • typename... defines a template parameter pack
  • Args... defines a function parameter pack
  • (args + ...) is a fold expression, meaning (E~1~ + (... + (E~N-1~ + E~N~))), where E~i~ is the i-th element in the pack expansion.
  • if the fold is used with a empty pack expansion, only the following operators are allowed:
    • &&: empty pack denotes true
    • ||: empty pack denotes false
    • comma operator ,: empty pack denotes void()

Pack expansions in using-declarations

Allows you to inject names with using-declarations from all types in a parameter pack.

代码语言:javascript
复制
template<class... Ts>
struct overloaded : Ts... {
  using Ts::operator()...;
};

Nested namespace definition

Allows you to write: namespace A::B::C { /* … */ } Rather than: namespace A { namespace B { namespace C {/* … */ }}}

Attribute Features

  • [[fallthrough]] - indicates that a case in a switch statement can fallthrough.
  • [[nodiscard]] - specifies that a return value should not be discarded, there’s warning reported otherwise.
  • [[maybe_unused]] - the compiler will not warn about a variable that is not used.

Ignore unknown attributes - compilers which don't support a given attribute will ignore it. Previously it was unspecified.

Using attribute namespaces without repetition – simplifies using attributes from the same namespace

Attributes for namespaces and enumerators – Fixes the spec, so now attributes can be used for most of the declarations, variables, classes, enums, namespaces, enum values, etc.

Lambda capture of *this

this pointer is implicitly captured by lambdas inside member functions.

Now you can use *this when declaring a lambda and this will create a copy of the object. Capturing by value might be especially important for async invocation, parallel processing.

New auto rules for direct-list-initialization

auto x { 1 }; will be now deduced as int, but before it was an initializer list

Typename in a template template parameter

You can now use typename instead of class when declaring a template template parameter.

Removing Dynamic Exception Specifications

  • Dynamic exception specifications throw() is deprecated in C++11 and is identical to noexcept(true) in C++17, and it will be removed in C++20
  • Explicit dynamic exception specification throw(typeid, typeid, ..) is deprecated in C++11 and removed in C++17.

Exception specifications part of the type system

Previously exception specifications for a function didn’t belong to the type of the function, but it will be part of it.

Aggregate initialization of classes with base classes

If a class was derived from some other type you couldn’t use aggregate initialization. But now the restriction is removed.

Memory allocation for over-aligned data

C++11/14 did not specify any mechanism by which over-aligned data can be dynamically allocated (i.e. respecting the alignment of the data).

Now, we get new functions that takes alignment parameters.

Like void* operator new(std::size_t, std::align_val_t);

__has_include in preprocessor conditionals

This feature allows a C++ program to directly, reliably and portably determine whether or not a library header is available for inclusion.

Guaranteed copy elision

Copy elision (e.g. RVO) was a common compiler optimization, now it’s guaranteed and defined by the standard!

Direct-list-initialization of enumerations

You can now initialize enum class with a fixed underlying type:

代码语言:javascript
复制
enum class Handle : uint32_t {
  Invalid = 0
};
Handle h { 42 }; // OK

Stricter expression evaluation order

In expression such as f(a, b, c): the order of evaluation of a, b, c is still unspecified, but any parameter is fully evaluated before the next one is started. Plus other “practical” changes:

  • Postfix expressions are evaluated from left to right.
  • Assignment expressions are evaluated from right to left.
  • Operands to shift operators are evaluated from left to right. The code below now evaluates as f, h, g, i (previously any order)std::cout << f() << g(h()) << i();

Differing begin and end types in range-based for

Types of __begin and __end iterators (used in the loop) will be different; only the comparison operator is required. This little change improves Range TS experience.

Other

  • static_assert with no message
  • u8 character literals
  • Removing trigraphs
  • Remove Deprecated Use of the register Keyword
  • Remove Deprecated operator++(bool)
  • Hexadecimal floating-point literals
  • Allow constant evaluation for all non-type template arguments
  • New specification for inheriting constructors
  • Matching of template template-arguments update
  • Removal of std::auto_ptr, std::random_shuffle, and more
  • Removal of std::result_of. Introduced std::invoke_result, std::invoke, std::apply
  • type traits helpers: std::is_same_v
  • std::optional merged from boost
  • std::vairant merged from boost
  • std::any merged from boost

References

  • http://www.bfilipek.com/2017/01/cpp17features.html,
  • https://isocpp.org/,
  • https://herbsutter.com/,
  • http://en.cppreference.com/w/cpp/compiler_support,
  • http://baptiste-wicht.com/,
  • https://tartanllama.github.io/,
  • https://jonasdevlieghere.com/,
  • https://leanpub.com/cpp17indetail
  • https://www.codingame.com/playgrounds/2205/7-features-of-c17-that-will-simplify-your-code/introduction
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Toddler的笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 笔者序
  • 1.Structured Binding
  • 2.CTAD (Class template argument deduction)
  • 3.Init-statements for if and switch
  • 4.constexpr if-statements
  • 5.constexpr lambda expressions
  • 6.Inline variables
  • 7.Non-type template parameters with auto type
  • 8.Fold Expression
  • Pack expansions in using-declarations
  • Nested namespace definition
  • Attribute Features
  • Lambda capture of *this
  • New auto rules for direct-list-initialization
  • Typename in a template template parameter
  • Removing Dynamic Exception Specifications
  • Exception specifications part of the type system
  • Aggregate initialization of classes with base classes
  • Memory allocation for over-aligned data
  • __has_include in preprocessor conditionals
  • Guaranteed copy elision
  • Direct-list-initialization of enumerations
  • Stricter expression evaluation order
  • Differing begin and end types in range-based for
  • Other
  • References
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档