postgame

https://en.wikipedia.org/wiki/C%2B%2B14

영문 위키피디아를 번역했습니다.

틀리면 틀린데로~ 맞으면 맞는데로~

-----------


c++ 14는 C++ ISO/IEC 표준의 가장 최신 개정에 대한 비공식 이름으로, 정식으로는 국제 표준 ISO/IEC 14882:2014(E) 프로그래밍 랭귀지 C++이다. C++14는 C++11의 소규모 확장으로, 주요 버그 수정과 소규모 향상을 의향으로 시행되었다. 위원회 C++14 위원회 표준 초안은 N3690은 2013년 5월 15일에 발표되었다. 규격초안 N3936은 2014년 3월 2일에 발표되었고, 최종 투표 기간은 2014년 8월 15일로 마무리되었고, 그 결과(만장일치) 8월 18일에 공표되었다.


C++ 표준 개정은 이미 두드러지게 늦어졌기 때문에, C++ 1y라는 이름이 때때로 대신 사용된다. 유사하게 C++ 11표준은 2010년 이전에 릴리즈에 대한 기대로 'C++0x' 로 사용되었다. (실은 2010년을 넘어 2011에 최종확정되었다.)


아래 피쳐들은 작업초안 N3797에서 서술된 것들이다. 이들중 상대적으로 마이너라 표준에서 최종 안에 업데이트 되지 않은 것도 포함한다.


내용


1. 새로운 랭귀지 피쳐

1.1 리턴타입 추론 함수

1.2 선언에서 교체 타입 추론

1.3 관대한 constexper 제한

1.4 변수 템플릿

1.5 총합 멤버 초기화

1.6 바이러니 리터널

1.7 숫자 격리자

1.8 제네릭 람다

1.9 람다 캡쳐 표현식

1.10 어트리뷰트[[deprecated]]

2. 새로운 표준 라이브러리 피쳐

2.1 쉐어드 뮤텍스와 락킹

2.2 연합 컨테이너에서의 이종의 룩업

2.3 표준 유저 정의 리터널

2.4 타입 경유 튜플 어드레싱

2.5 작은 라이브러리 피쳐

3. 더 보기

4. 레퍼런스

5. 외부 링크


새로운 랭귀지 피쳐

-----------------------

C++14 언어 핵심에 추가된 피쳐들이다.


리턴 타입 추론 함수

C++ 11은 리턴 상태를 주는 표현 타입에 근거에서 리턴 타입을 추론하는 람다 표현식을 허용했다.

C++ 14는 모든 함수에 이것을 제공한다. 람다 함수로의 편의가 확장되었는데 return expression; 형식을 가지고 있지 않은 함수에 대해 타입 추론 리턴을 허용한다. 리턴타입 추론을 하기 위해서 함수는 반드시 auto로 리턴타입을 선언해야만 한다. 그러나 C++11에서는 후행 리턴 타입이 없다.


auto DeduceReturnType(); 리턴타입이 결정된다.


만약 여러개의 리턴타입이 함수 구현에서 사용되었다면, 모두 같은 타입으로 추론 되어야만 한다.

함수는 리턴 타입의 추론을 앞에서의 선언으로 할 수 있으나 정의되기 전까지는 사용할 수는 없다. 그정의에서 사용하는 변환 유닛은 반드시 유효해야만 한다.


재귀는 이 타입의 함수에서 사용할 수 있다. 그러나 재귀 호출은 함수의 정의에서 최소한 한번 리턴 상태이후에 발생한다.


auto Correct(int i) { if (i == 1) return i; // int로 추론한 타입 리턴 else return Correct(i-1)+i; // 이것은 이제 호출된다. } auto Wrong(int i) { if (i != 1) return Wrong(i-1)+i; // 호출하기엔 이르다. 이전 리턴 상태가 없다. else return i; // int로 추론한 타입 리턴 }


선언에서 교차 타입 추론

c++ 11에서 타입 추론을 하는 2가지 방법이 추가되었었다. auto는 적당한 타입으로 변수를 생성하는 방법이고 이는 표현식에 기반한다. decltype은 표현식의 타입을 계산하는 방법이다. 그러나 decltype와 auto추론 방법은 다르다. 특히 auto는 std::remove_reference으로 사용될 때 처럼, 항상 비참조 타입으로 추론되는 반면 auto&&는 항상 참조 타입으로 추론된다. 그러나 decltype는 표현식의 값 카테고리 기반과 표현식이 유추하는 특징을 기반으로 비참조 타입 또는 참조 타입을 추론하도록 자극한다.


int i; int&& f(); auto x3a = i; // decltype(x3a) 는 int decltype(i) x3d = i; // decltype(x3d) 는 int auto x4a = (i); // decltype(x4a) 는 int decltype((i)) x4d = (i); // decltype(x4d) 는 int& auto x5a = f(); // decltype(x5a) 는 int decltype(f()) x5d = f(); // decltype(x5d) 는 int&&


C++ 14는 decltype(auto) 문법이 추가되었다.이것은 주어진 표현식에서 decltype을 사용한 auto 선언을 허용한다.

decltype(auto) 문법으로 함수 리턴 타입 추론에 대해 auto를 대신해서 decltype(auto)를 사용할 수도 있다.


관대한 constexpr 제한

C++11은 선언한 constexpr 함수 개념을 도입했다. 정수형 템플릿 인자처럼 상수 표현을 요하는 명령은 리턴 값을 가진 함수는 컴파일 타임에 수행된다. 그러나 C++ constexpr 함수는 오직 static_assert와 기타 몇몇 선언만 되는 단일 표현식만 사용할 수 있었다.

C++ 14는 이 규정이 관대해졌다. constexpr 선언 함수는 현재 아래를 포함한다.

+ 몇몇 선언은 제외:

 + static 또는 thread_local 변수들

 + 초기화 없는 변수 정의 

+ 조건부 분기 상태 if와 switch

+ for기반을 포함한 모든 루프 상태

+ 상수 표현 함수내에서 오브젝트의 생명주기가 시작되었고, 이 오브젝트의 값을 변경하는 표현식. 이것은  const가 아니고, constexpr 선언된 비static멤버 함수 호출을 포함한다.


C++14의 느슨한 constexpr 선언 함수에서는 goto 가 금지된다. 

또한 C++11에서는 this에 관해서 constexpr로 선언된 모든 비 static 멤버 함수를 암묵적으로 const로 선언된다. 이것이 삭제된 이후, 비 static 멤버 함수는 비 const가 될 수 있다. 그러나 이같은 금기는 비 const constexpr 멤버 함수는 상수 표현식 안에서 시작한 생명주기를 가지는 오브젝트인 클래스 멤버만 수정 할 수 있다.


변수 템플릿

이전 C++ 버젼에서는, 오직 함수, 클래스와 타입 얼리어스만 템플릿이 될 수 있었다. C++ 14에서는 변수의 생성도 템플릿이 되는 것을 허용한다. 제안에서 주어진 예제는 변수 타입에 대해 pi의 값을 가져와 읽을 수 있는 변수 pi다.(예, 3을 내장된 타입으로 읽었을 때, 즉 float, double, long double 정밀도와 가장 가까운 값이 가능하다.)

이 템플릿의 통상 규칙은 선언과 정의, 일반화를 포함해서 적용된다.


총합 멤버 초기화

C++11은 멤버 초기화가 추가되었다. 생성자에서 초기화한다면 클래스 스코프내에서 멤버에 적용하는 표현식은 멤버를 초기화 할 수 없었다.총합의 정의는 멤버 초기화를 하는 특정 클래스를 명확하게 제외하기 위해 바뀌였다. 그래서 그들은 총합 초기화가 허용되지 않았다.

c++ 14는 이 같은 타입에서 총합 초기화를 허용하는 것으로 금지조항이 느슨해졌다. 만약 braced init 리스트가 인자에 대해 값을 제공하지 않는다면, 멤버 초기화가 그것을 처리한다.


바이러니 리터널

C++14의 숫자 리터널은 2진수로 명기한다. 문법으로 0b나 0B를 접두사로 사용한다. 이 문법은 자바나 OCaml 등 다른 언어에서도 사용되고, 2007년 이후 일부 C 컴파일러에서 비공식 확장으로도 사용되고 있다.


숫자 구분자

C++14에서는 숫자 리터널내의 단일 인용구(') 캐릭터를 임의로 사용할 수 있게 되었다. 정수 리터널과 부동소수점 리터널 둘다 적용되고, 이것은 사람이 큰 숫자를 분리해 읽기 편하게 만들어 준다.


auto integer_literal = 1'000'000;
auto floating_point_literal = 0.000'015'3;
auto binary_literal = 0b0100'1100'0110;
auto silly_example = 1'0'0'000'00;


제네릭 람다

C++11에서, 람다 함수 패러미터는 콘크리트 타입의 선언이 필요했다. C++14는 이 요구가 느슨해졌는데, 람다표현 패러미터가 auto 타입 명시자로 선언 할 수 있게 되었다.


auto 타입 추론에 대해 말하자면, 제네릭 람다는 템플릿 아큐먼트 추론 룰을 따른다.(완전히 동일하진 않다.)  위 코드는 아래와 동일하다.


struct unnamed_lambda
{
  template<typename T, typename U>
    auto operator()(T x, U y) const {return x + y;}
};
auto lambda = unnamed_lambda{};


람다 캡쳐 표현식

C++11 람다 함수 캡쳐 변수는 값 복사나 참조로 스코프 밖에서 선언된다. 람다의 값 멤버는 move-only 타입이 될수 없다는 것을 의미한다. C++14에서는 임의 표현식으로 캡쳐 멤버의 초기화를 허용한다.이것은 스코프 밖에서 명명된 변수 없이, 람다의 단독 멤버 선언이나 value-move의 의한 캡쳐 둘다 허용된다.

이것은 초기화 표현식의 사용을 경유하여 완료된다.


auto lambda = [value = 1] {return value;};


이 람다 함수 lambda는 초기화된 value로 1을 리턴한다. 이 선언된 캡쳐는 auto에 의한 것처럼 초기화 함수로 부터 타입이 추론된다.

이는 std::move 함수의 사용시, 이동의 의한 캡쳐로 사용된다. 


std::unique_ptr<int> ptr(new int(10));
auto lambda = [value = std::move(ptr)] {return *value;};


어트리뷰트 [[deprecated]]

deprecated 속성은 deprecated 엔티티를 만드는 것을 허용한다. 이것은 아직 정식으로 사용되지만, 사용자에게 사용 자제를 공지하고, 편집기간 동안 경고 메세지를 보여준다.

스트링 리터널 옵션으로 반대하는 이유나 대체를 제안하는 것을 deprecated 인자로 나타나게 할 수 있다. 


[[deprecated]] int f();
 
[[deprecated("g() is thread-unsafe. Use h() instead")]]
void g( int& x );
 
void h( int& x );
 
void test() {
  int a = f(); // warning: 'f' is deprecated
  g(a); // warning: 'g' is deprecated: g() is thread-unsafe. Use h() instead
}



새로운 표준 라이브러리 피쳐

--------------------------------------------------------------------

공유 뮤텍스와 락킹

C++ 14는 shared timed mutex와 companion shared lock type이 추가되었다.


연합 컨테이너내 이종 룩업

C++ 표준 라이브러리에서 4가지 연합 컨테이너 클래스가 정의된다. 이 클래스들은 자신의 타입의 값 기반으로 사용자가 값을 찾는 것을 허용한다. 맵 컨테이너는 키와 리턴 값으로 룩업이 끝나는 곳에선 사용자가 키와 값 명시하는 것을 허용한다. 그러나 룩업은 맵 안의 키이거나 셋팅된 값의 뚜렷한 키 타입으로 항상 끝나게 된다.  


C++14는 비교 오퍼레이터가 실제 키 타입과 비교 할 수 있기만 하면 임의 타입을 경유해서 룩업이 끝나는 것을 허용한다. 이것은 맵이 std::string에서 특정 값까지 const char* 또는 operator< 오버로드가 가용한 다른 타입과도 비교하는 것을 허용한다. 

 

후방향 호환성을 위해, 이종 룩업은 오직 연관 컨테이너가 비교기를 제공 했을 때만 가능하다. 표준 라이브러리 클래스 std::less<>와 std::greater<>은 이종 룩업을 허용하기 위해 증대되었다.


표준 사용자 정의 리터널

C++11은 사용자 정의 리터널 접미사에 대한 문법을 정의했었다. 그러나 표준 라이브러리는 이것을 하나도 사용하지 않았다. C++14는 다음 표준 리터널이 추가되었다.


"s" 는  여러가지 std::basic_string 타입 생성에 대한 것이다.

"h", "min", "s", "ms", "us", "ns" 는 시간 간격 std::chrono::duration에 대응 생성하는 것에 대한 것이다.


string str = "hello world"s;
chrono::duration dur = 60s;


2개의 "s" 리터널은 상호작용하지 않는다. 문자열은 문자열 리터널에서만 작동하고, 초는 숫자에서만 작동한다.


타입 경유 튜플 어드레싱  

std::tuple 타입이 C++11에서 도입되었는데, 이는 컴파일 시간 상수 정수형으로 인덱스되는 타입 값의 총합을 허용한다. C++ 14는 이것이 인덱스 대신에 타입으로 튜플에서 가져오는 것으로 확장되었다. 만약 튜플이 그 타입의 요소가 하나 이상이라면 컴파일 타임에 에러를 받게 된다.


tuple<string, string, int> t("foo", "bar", 7); int i = get<int>(t); // i == 7 int j = get<2>(t); // 앞과 같다.: j == 7 string s = get<string>(t); // 모호성 때문에 컴파일 타임 에러


작은 라이브러리 피쳐

std::make_unique 는 std::make_shared 처럼 std::unique_ptr 오브젝트에 대해 사용할 수 있다.

std::integaral_constant는 상수 값 리턴을 오버로드한 operator()을 얻는다.

전역 std::begin.std::end 함수와 std::cbegin/std::cend 함수는 증강된다. 범위의 시작과 끝 상수 이터레이터를 리턴하게 된다.

Posted by 중원_