C++17 새로운 특성 개인 총화

17773 단어 C++17새로운 특성
C++17
컴 파 일 러 버 전:GCC 7.1,Clang 5.0
__cplusplus:201703L
컴 파일 옵션:-std=c+17
키워드
1.1 constexpr
constexpr 사용 범 위 를 확장 합 니 다.if 구문 에 도 사용 할 수 있 고 lambda 표현 식 에 도 사용 할 수 있 습 니 다.
예 1:

#include<iostream>
 
template<bool ok>
constexpr void foo()
{
 //        ,if else       
 if constexpr (ok == true)
 {
  // ok true ,   else        
  std::cout << "ok" << std::endl;
 }
 else
 {
  // ok false ,   if        
  std::cout << "not ok" << std::endl;
 }
}
 
int main()
{
 foo<true>();//  ok,         std::cout << "ok" << std::endl;   
 foo<false>();//  not ok,         std::cout << "not ok" << std::endl;   
 return 0;
}

예 2:

int main()
{
 constexpr auto add1 = [](int n, int m){
  auto func1 = [=] { return n; }; //func1 lambda   
  auto func2 = [=] { return m; }; //func2 lambda   
  return [=] { return func1() + func2(); };
 };
 constexpr auto add2 = [](int n, int m){
  return n + m;
 };
 auto add3 = [](int n, int m){
  return n + m;
 };
 int sum1 = add1(30, 40)( ); //     ,add1      ,    70
 int sum2 = add2(sum1, 4); //     constexpr  ,add2 constexpr  ,     lambda
 constexpr int sum3 = add3(1, 2); //sum3 constexpr  ,     ,add3     lambda,    3
 int sum4 = add2(10, 2);//     ,add2      ,    12
 return 0;
}
1.2 static_assert
확장 staticassert 용법,정적 단언 의 디 스 플레이 텍스트 를 선택 할 수 있 습 니 다.
예:

static_assert(true, "");
static_assert(true);//c++17  
1.3 auto
auto 추정 범위 확장
예:

auto x1 = { 1, 2 }; //   std::initializer_list<int>  
auto x2 = { 1, 2.0 }; //  :     ,    
auto x3{ 1, 2 }; //  :auto            
auto x4 = { 3 }; //   std::initializer_list<int>  
auto x5{ 3 }; //   int  
1.4 typename
확장 용법 은 템 플 릿 의 템 플 릿 인자 에 나타 날 수 있 습 니 다.
먼저 type:name 의 용법 을 돌 이 켜 보면 ① 템 플 릿 에 사용 되 며 템 플 릿 매개 변 수 를 유형 으로 표시 합 니 다.② 어떤 이름 이 변수 이름 임 을 설명 하 는 데 사 용 됩 니 다.
예 1:

struct A
{
 typedef int Example;
};
//     :         
template<typename T>
struct B { };
 
struct C
{
 typedef typename A::Example E;//     :          
};
 
int main()
{
 typename A::Example e;//     :          
 return 0;
}
새로운 기능 의 type:name 용법,
예 2:

#include<iostream>
#include<typeinfo>
 
template<typename T>
struct A
{
 int num;
 A()
 {
  std::cout << "A Construct" << std::endl;
  std::cout << "template typename is: " << typeid (T).name() << std::endl;
 }
};
//   T   ,X      ,T X  typename    class
template<template<typename T> typename X>
struct B
{
 X<double> e;
 B() { std::cout << "B Construct" << std::endl; }
};
 
int main()
{
 A<B<A>> a;
 std::cout << "***************************" << std::endl;
 B<A> b;
 return 0;
}
실행 결과:

1.5 inline
확장 용법 은 내 연 변 수 를 정의 하 는 데 사용 되 며,기능 은 내 연 함수 와 비슷 합 니 다.inline 은 함수 나 변수 가 다 중 으로 정의 되 는 문 제 를 피 할 수 있 습 니 다.같은 함수 나 변 수 를 정의 하고 이 함수 나 변 수 를 inline 으로 설명 하면 컴 파일 러 는 이 함수 나 변 수 를 자동 으로 연결 합 니 다.
(오류 가 발생 하지 않 음):

// test.h
inline void print()
{
 std::cout << "hello world" << std::endl;
}
 
inline int num = 0;
// func.h
include "test.h"
inline void add(int arg)
{
 num += arg;
 print();
}
// main.cpp
include "func.h"
int main()
{
 num = 0;
 print();
 add(10);
 return 0;
}

문법
2.1 접 이식
길 어 지 는 매개 변수 템 플 릿 의 패키지 해제 에 사용 되 며,각종 연산 자(연산 자 와)만 지원 하 며,왼쪽,오른쪽 으로 나 누 어 접 습 니 다.
예:

#include<string>
 
template<typename ... T>
auto sum(T ... arg)
{
 return (arg + ...);//   
}
 
template<typename ... T>
double sum_strong(T ... arg)
{
 return (arg + ... + 0);//   
}
 
template<typename ... T>
double sub1(T ... arg)
{
 return (arg - ...);//   
}
 
template<typename ... T>
double sub2(T ... arg)
{
 return (... - arg);//   
}
 
int main()
{
 int s1 = sum(1, 2, 2, 4, 5);//  :((((1+)2+)3+)4+)5 = 15
 double s2 = sum(1.1, 2.2, 3.3, 4.4, 5.5, 6.6);
 double s3 = sum(1, 2.2, 3, 4.4, 5);
 
 double s4 = sub1(5, 2, 1, 1);//  :((((5-)2-)1-)1) = 1
 double s5 = sub2(5, 2, 1, 1);//  :(5-(2-(1-(1)))) = 3
 
 double s6 = sum_strong();//s6 = 0
 
 std::string str1("he");
 std::string str2("ll");
 std::string str3("o ");
 std::string str4("world");
 std::string str5 = sum(str1, str2, str3, str4);//str5 = "hello world"
 return 0;
}
2.2 구조 화 귀속
하나 이상 의 변 수 를 포함 하 는 중 괄호 로 구조 화 바 인 딩 을 표시 하지만 구조 화 바 인 딩 을 사용 할 때 는 auto 키워드,즉 정시 성명 변 수 를 묶 어야 합 니 다.
예 1:

/*
 *   :    
 */
struct S
{
 double num1;
 long num2;
};
 
S foo(int arg1, double arg2)
{
 double result1 = arg1 * arg2;
 long result2 = arg2 / arg1;
 return {result1, result2};//     S  
};
 
int main()
{
 auto [num1, num2] = foo(10, 20.2);//    num1 double,num2 long
 return 0;
}
예 2:

#include<list>
#include<map>
 
/*
 *   :    
 */
template<typename T, typename U>
struct MyStruct
{
 T key;
 U value;
};
 
int main()
{
 std::list<MyStruct<int, double>> Container1;
 std::map<int, MyStruct<long long, char>> Container2;
 for(auto [key, value] : Container1)
 {
  //key int  ,value double  
 }
 for(auto [key, value] : Container2)
 {
  //key int  ,value MyStruct<long long, char>  
  //value1 long long  ,value2 char  
  auto [value1, value2] = value;
 }
 return 0;
}
2.3 비 유형 템 플 릿 매개 변 수 를 상수 로 계산 할 수 있 습 니 다.
비 형식 템 플 릿 매개 변 수 는 클래스 의 정적 구성원 에 게 전 달 될 수 있 습 니 다.
예:

class MyClass
{
public:
 static int a;
};
 
template<int *arg>
void foo() {}
 
int main()
{
 foo<&MyClass::a>();
 return 0;
}
2.4 조건 부 분기 문 초기 화
if 와 switch 에서 초기 화 가능
예:

template<long value>
void foo(int &ok)
{
 if constexpr (ok = 10; value > 0)
 {
 
 }
}
 
int main()
{
 int num = 0;
 if(int i = 0; i == 0)
 {
 
 }
 foo<10>(num);
 switch(int k = 10; k)
 {
  case 0:break;
  case 1:break;
  default:break;
 }
 return 0;
}
2.5 중합 초기 화
대상 을 초기 화 할 때 괄호 로 구성원 에 게 값 을 부여 할 수 있 습 니 다.
예:

struct MyStruct1
{
 int a;
 int b;
};
 
struct MyStruct2
{
 int a;
 MyStruct1 ms;
};
 
int main()
{
 MyStruct1 a{10};
 MyStruct2 b{10, 20};
 MyStruct2 c{1, {}};
 MyStruct2 d{{}, {}};
 MyStruct2 e{{}, {1, 2}};
 return 0;
}
2.6 내장 네 임 스페이스
다 중 네 임 스페이스 의 작성 을 간소화 하 다.
예:

//    
namespace A
{
 namespace B
 {
  namespace C
  {
 
  };
 };
};
//   
namespace A::B::C
{
 
};
2.7 lambda 표현 식 캡 처*this 값
lambda 표현 식 은*this 의 값 을 캡 처 할 수 있 지만 this 와 그 구성원 은 읽 기 전용 입 니 다.
예:

struct MyStruct {
 double ohseven = 100.7;
 auto f() {
  return [this] {
   return [*this] {
    this->ohseven = 200.2;//  ,        
    return ohseven;//  
   };
  }();
 }
 auto g() {
  return []{
   return [*this]{};//  ,  lambda       this
  }();
 }
};
2.8 매 거 대상 의 구조
매개[클래스]대상 에 게 값 을 부여 할 수 있 습 니 다.
예:

enum MyEnum { value };
MyEnum me {10};//  :   int     MyEnum    
 
enum byte : unsigned char { };
byte b { 42 }; //  
byte c = { 42 }; //  :   int     byte    
byte d = byte{ 42 }; //  ,   b  
byte e { -1 }; //  :     -1       byte  
 
struct A { byte b; };
A a1 = { { 42 } }; //  :   int     byte    
A a2 = { byte{ 42 } }; //  
 
void f(byte);
f({ 42 }); //  :      
 
enum class Handle : unsigned int { value = 0 };
Handle h { 42 }; //  
2.9 16 진 단일 정밀도 부동 소수점 숫자 액면가
0x 접두사 로 시작 하 는 16 진수,f 접두사 의 단일 정밀도 부동 소수점,합병 하면 16 진수 의 단일 정밀도 부동 소수점 이 있 습 니 다.
예:

int main()
{
 float value = 0x1111f;
 return 0;
}
2.10 메모리 정렬 기반 동적 메모리 할당
동적 메모리 할당 에 대해 서 는 new 와 delete 연산 자가 빠 질 수 없습니다.새로운 표준 의 new 와 delete 연산 자 는 메모리 값 을 맞 추고 메모리 공간 을 분배 하고 방출 하 는 기능 을 추 가 했 습 니 다.(즉,메모리 값 을 맞 추 는 new,delete 연산 자 를 다시 불 러 옵 니 다)
함수 원형:

void* operator new(std::size_t size, std::align_val_t alignment);
void* operator new[](std::size_t size, std::align_val_t alignment);
 
void operator delete(void*, std::size_t size, std::align_val_t alignment);
void operator delete[](void*, std::size_t size, std::align_val_t alignment);
매개 변수 설명:
분 배 된 바이트 수.alignment 의 정수 배 여야 합 니 다.
alignment―지정 한 메모리 값 정렬.반드시 지 지 를 실현 하 는 합 법 적 인 정렬 이 어야 한다.
new 의 반환 값:
성공,새 할당 메모리 의 시작 주 소 를 가리 키 는 지침 을 되 돌려 줍 니 다.
용법 예:

#include<new>
 
struct alignas(8) A {};
 
int main()
{
 A *a = static_cast<A *>(::operator new(sizeof(A), static_cast<std::align_val_t>(alignof (A))));
 ::operator delete(a, sizeof(A), static_cast<std::align_val_t>(alignof (A)));
 return 0;
}
2.11 세분 화 식 의 계산 순서
범용 프로 그래 밍 과 과부하 연산 자의 광범 위 한 사용 을 지원 하기 위해 새로운 기능 은 계산 순 서 를 세분 화 합 니 다.
다음 논란 코드 세그먼트:

#include<map>
 
int main()
{
 std::map<int, int> tmp;
 //  std::map []       ,   []  key ,std::map             
 tmp[0] = tmp.size();//         {0, 0}  {0, 1}
 return 0;
}
이 상황 을 해결 하기 위해 새로운 계산 순서 규칙 은 다음 과 같다.
① 접미사 표현 식 은 왼쪽 에서 오른쪽으로 값 을 구한다.이것 은 함수 호출 과 구성원 선택 표현 식 을 포함 합 니 다.
② 할당 식 은 오른쪽 에서 왼쪽으로 값 을 구 합 니 다.이것 은 복합 할당 을 포함한다.
③ 왼쪽 에서 오른쪽으로 이동 연산 자의 조작 수 를 계산한다.
2.1.2 템 플 릿 류 의 템 플 릿 매개 변수 자동 유도
템 플 릿 클래스 의 대상 을 정의 할 때 템 플 릿 파 라 메 터 를 지정 하지 않 아 도 되 지만 구조 함수 에서 템 플 릿 파 라 메 터 를 유도 해 야 합 니 다.
예:

template<class T> struct A {
 explicit A(const T&, ...) noexcept {} // #1
 A(T&&, ...){} // #2
};
 
int i;
A a1 = { i, i }; //오류,\#1 에 따라 오른쪽 값 으로 유도 할 수 없고\#1 을 통 해 복사 초기 화 할 수 없습니다.
A a2{i, i}; //정확,호출\#1 초기 화 에 성 공 했 습 니 다.a2 는 A형식 으로 유도 합 니 다.
A a3{0, i}; //정확 합 니 다.호출\#2 초기 화 에 성 공 했 습 니 다.a2 는 A형식 으로 유도 합 니 다.
A a4 = {0, i}; //정확 합 니 다.호출\#2 초기 화 에 성 공 했 습 니 다.a2 는 A형식 으로 유도 합 니 다.

template<class T> A(const T&, const T&) -> A<T&>; // #3
template<class T> explicit A(T&&, T&&) -> A<T>; // #4
A a5 = {0, 1}; //오류,\#1 과\#2 구조 함수 결과 가 같 습 니 다(즉 충돌).\#3 에 따라 A유형 으로 유도 합 니 다.
A a6{0, 1}; //정확 합 니 다.\#2 를 통 해 A유형 으로 추정 합 니 다.
A a7 = {0, i}; //오류,비 정적 왼쪽 값 을 오른쪽 값 으로 연결 할 수 없습니다.\#3 에 따라 A유형 으로 유도 합 니 다.
A a8{0, i}; //오류,비 정적 왼쪽 값 을 오른쪽 값 으로 연결 할 수 없습니다.\#3 에 따라 A유형 으로 유도 합 니 다.

template<class T> 
struct B {
 
 template<class U> 
 using TA = T;//    
 
 template<class U> 
 B(U, TA<U>);//    
};
B b{(int*)0, (char*)0}; //정확,B유형 으로 유도
2.13 중복 네 임 스페이스 의 속성 목록 간소화
예:

[[ using CC: opt(1), debug ]] void f() {}
//      [[ CC::opt(1), CC::debug ]] void f() {}
2.14 지원 되 지 않 고 표준 이 아 닌 속성
속성 목록 을 추가 할 때 컴 파 일 러 는 지원 하지 않 는 비표 준 속성 을 무시 하고 경고 와 오 류 를 보 내지 않 습 니 다.
2.15 개작 과 계승 구조 함수
클래스 의 계승 체계 에서 구조 함수 의 자동 호출 은 골 치 아 픈 문제 이다.새로운 특성 은 계승 과 구조 함수 의 용법 을 도입 한다.
예 1:

#include<iostream>
 
struct B1
{
 B1(int) { std::cout << "B1" << std::endl; }
};
 
struct D1 : B1 {
 using B1::B1;//    B1     
};
 
D1 d1(0); //  ,             ,  B1::B1(int)
예 2:

#include<iostream>
 
struct B1
{
 B1(int) { std::cout << "B1" << std::endl; }
};
 
struct B2
{
 B2(int) { std::cout << "B2" << std::endl; }
};
 
struct D1 : B1, B2 {
 using B1::B1;//    B1     
 using B2::B2;//    B2     
};
D1 d1(0); //  :    ,
 
struct D2 : B1, B2
{
 using B1::B1;
 using B2::B2;
 //  ,D2::D2(int)   B1::B1(int) B2::B2(int)。    B1 B2         ,        B1 B2     
 D2(int) : B1(1), B2(0)
 { std::cout << "D2" << std::endl; }
};
 
struct D3 : B1 
{
 using B1::B1;
};
D3 d3(0);//  ,  B1     ,   B1         ,  B1
 
//     
int main()
{
 D2 d(100);//    ,  B1 B2 D2
 return 0;
}
예 3:

#include<iostream>
 
struct B1
{
 B1() { std::cout << "B1 default" << std::endl; }
 B1(int) { std::cout << "B1" << std::endl; }
};
 
struct B2
{
 B2() { std::cout << "B2 default" << std::endl; }
 B2(int) { std::cout << "B2" << std::endl; }
};
 
struct D1 : B1, B2
{
 using B1::B1;
 using B2::B2;
 //  ,D2::D2(int)   B1::B1(int) B2::B2(int),        B1 B2     
 D1(int) : B1(1), B2(0)
 { std::cout << "D2" << std::endl; }
 //       ,                           
 D1() { std::cout << "D2 default" << std::endl; }
};
//     
int main()
{
 D1 d(100);//    ,  B1 B2 D2
 D1 dd;
 //  
 //B1 default
 //B2 default
 //D2 default
 return 0;
}
2.16 내 연 변수
보이다
2.17 auto 를 비 유형 템 플 릿 매개 변수 로 사용 합 니 다.
템 플 릿 매개 변수 가 비 형식 일 때 auto 자동 유도 형식 을 사용 할 수 있 습 니 다.
예:

#include<iostream>
 
template<auto T>
void foo()
{
 std::cout << T << std::endl;
}
 
int main()
{
 foo<100>();//  100
 foo<int>();//no matching function for call to "foo<int>()"
 return 0;
}
3 매크로
3.1 __has_include
어떤 파일 이 포함 되 어 있 는 지 판단 합 니 다.
예:

int main()
{
#if __has_include(<cstdio>)
 printf("hehe");
#endif
#if __has_include("iostream")
 std::cout << "hehe" << std::endl;
#endif
return 0;
}
4 속성
4.1 fallthrough
switch 구문 블록 에 사용 하면 다음 케이스 나 default 를 실행 할 것 임 을 표시 합 니 다.
예:

int main()
{
 int ok1, ok2;
 switch (0)
 {
  case 0:
  ok1 = 0;
  [[fallthrough]];
  case 1:
  ok2 = 1;
  [[fallthrough]];
 }
 return 0;
}
4.2 nodiscard
클래스 성명,함수 성명,매 거 진 성명 에 사용 할 수 있 으 며 함수 의 반환 값 이 수신 되 지 않 았 음 을 나타 내 며 컴 파일 할 때 경고 가 나타 납 니 다.
예:

[[nodiscard]] class A {}; //         
[[nodiscard]] enum class B {}; //         
class C {};
 
[[nodiscard]] int foo()
{ return 10; }
 
[[nodiscard]] A func1() { return A(); }
[[nodiscard]] B func2() { return B(); }
[[nodiscard]] C func3() { return C(); }
 
int main()
{
 foo();//warning: ignoring return value
 func1();//warning: ignoring return value
 func2();//warning: ignoring return value
 func3();//warning: ignoring return value
 return 0;
}
4.3 maybe_unused
클래스,type:def,변수,비정 상 데이터 구성원,함수,매 거 진 또는 매 거 진 값 에 사용 할 수 있 습 니 다.컴 파일 러 가 사용 하지 않 은 실체 에 대한 경 고 를 억제 하 는 데 사용 된다.즉,이 속성 을 더 하면 어떤 실체 에 대해'쓸모 없다'는 경 고 를 하지 않 는 다.
용법 예:

[[maybe_unused]] class A {};
[[maybe_unused]] enum B {};
[[maybe_unused]] int C;
[[maybe_unused]] void fun();
결어
이번 검사 에 서 는 C++17 의 새로운 특성 에 GCC 컴 파 일 러 를 사 용 했 으 며,Clang 의 지원 성에 대해 서 는 차이 점 을 측정 하지 않 았 다.문제 가 있 으 면 지적 해 주 십시오.
C++17 의 새로운 특성 에 대한 개인 적 인 정리 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 C++17 의 새로운 특성 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 도 많은 응원 부탁드립니다!

좋은 웹페이지 즐겨찾기