noexcept

Modern C++에 적응하기
Effective Modern C++ Chapter 3. noexcept


noexcept

C++11에서 함수가 예외를 방출(emit)[1]하지 않는다면, 함수를 noexcept로 선언할 수 있다.
noexcept는 함수 예외 안정성의 명시적 보장이다. 이를 통해서 클라이언트는 함수를 호출할때 해당 함수가 예외 안정성을 보장하는지 알 수 있다.


noexcept는 컴파일러가 코드를 최적화하는데 참고하는 고려사항 중 하나이다.
C++98에서 예외 안정성이 보장된 함수(int f(int x) throw();)에서 예외가 방출되면(즉, 예외 명세가 위반되면), 호출 스택이 해당 함수를 호출한 지점에 도착할 때 까지 풀리며(unwind), 그 지점에서 몇 가지 동작 후 프로그램이 종료된다.

반면 C++11에서 같은 예외 명세를 가진 함수(int f(int x) noexcept;)의 예외 명세가 위반되면, 프로그램이 종료되기 전에 호출 스택이 풀릴수도있고 아닐 수도 있다.[2]

Read more

constexpr

Modern C++에 적응하기
Effective Modern C++ Chapter 3. constexpr


constexpr

constexpr은 해당 값이 const일 뿐만 아니라, 컴파일 타임 에 평가될 수 있음을 의미한다.

constexpr로 선언된 객체는 const이며, 그 값은 컴파일 타임에 정해진다. 따라서 컴파일 타임 이후에 평가되는 값으로 초기화할 수 없다.

1
2
3
4
5
int sz;
...

constexpr auto arrSize1 = sz; // error
constexpr auto arrSize2 = 10; // OK

컴파일 타임에 정해진 상수이므로 배열의 길이나 템플릿 인수 등, 정수 상수 표현식 에 사용할 수 있다.

Read more

iterator vs const_iterator

Modern C++에 적응하기
Effective Modern C++ Chapter 3. iterator vs const_iterator


iterator vs const_iterator

const를 사용하는 것이 의미가 있는 경우에는 항상 const를 사용하는 것이 바람직하다. iterator도 마찬가지이다.


C++98에서 const_iterator는 사용하기가 상당히 까다로웠다.
먼저 non-const 컨테이너로부터 const_iterator를 얻는 간단한 방법이 없었다.

1
2
3
4
5
6
7
8
9
10
typedef std::vector<int>::iterator IterT;
typedef std::vector<int>::const_iterator ConstIterT;

std::vector<int> values;
...

ConstIterT ci =
std::find(static_cast<ConstIterT>(values.begin()),
static_cast<ConstIterT>(values.end()),
1983);
Read more

Override-and-Final

Modern C++에 적응하기
Effective Modern C++ Chapter 3. Override and Final


override, final

함수 overriding을 위해서는 아래 조건을 만족해야 한다.

  • Base 클래스 함수가 virtual로 선언되어야 한다.
  • Base 클래스 함수와 이름이 동일해야 한다.(소멸자는 예외)
  • Base 클래스 함수와 매개변수 형식들이 동일해야 한다.
  • Base 클래스 함수와 const성이 동일해야 한다.
  • Base 클래스 함수의 반환 형식과 예외 명세가 호환되어야 한다.

C++11에서는 추가로 아래 한가지 조건을 더 만족해야 한다.

  • Base 클래스 함수와 참조 한정자[1]가 동일해야 한다.
Read more

Deleted-function

Modern C++에 적응하기
Effective Modern C++ Chapter 3. Deleted function


deleted function

C++98에서 사용을 금지하고싶은 멤버 함수는 private영역에 선언 후 정의하지 않았다.

1
2
3
4
5
6
7
template <typename charT, class traits = char_traits<charT>>
class basic_ios : public ios_base {
...
private:
basic_ios(const basic_ios&);
basic_ios& operator=(const basic_ios&);
};

이러한 형태의 함수는 private영역에 선언되어 있으므로 클라이언트가 외부에서 호출할 수 없다.
만약 접근 가능한 위치에서 호출한다고 하여도 선언만 있을뿐, 정의가 없기때문에 링크단계에서 실패한다.


Read more

Enum class

###DESCRIPTION_HERE###


enum class

enum class는 기존 enum의 문제점들을 보완하기 위해 등장하였다.

scope

enum에 선언된 내용은 enum과 같은 scope 범위를 갖는다.

1
2
3
enum Color { black, white, red };
...
int red = 0; // error
Read more

Alias declaration

Modern C++에 적응하기
Effective Modern C++ Chapter 3. Alias declaration


alias declaration

C++98의 typedef보다 더욱 직관적이고 효과적인 type declaration 이 C++11에 도입되었다.

1
2
3
using UptrMapSS = std::unique_ptr<std::unordered_map<std::string, std::string>>;

using FP = void (*)(int, const std::string&);

type declaration 은 템플릿화 할 수 있다.

Read more

nullptr

Modern C++에 적응하기
Effective Modern C++ Chapter 3. nullptr


nullptr

NULL0포인터 타입 이 아니다. 둘은 모두 정수 타입 으로 취급된다.

1
2
3
void f(int);
void f(bool);
void f(void*);

f(NULL);의 함수 호출은 NULL의 implementation에 따라 컴파일 오류를 발생시키거나 첫 번째 함수를 호출할 것이다.


Read more

Uniform initialization

Modern C++ 을 사용하면서 쉽게 지나치기 쉬운 새로운 기능들
중괄호 초기화


객체 초기화 방식

C++11에서 객체를 초기화하는 방법

1
2
3
4
int x( 0 ); 
int y = 0;
int z{ 0 };
int w = { 0 }; // 대체로 int w{ 0 }; 와 같음

객체의 초기화 과정에서 '='를 사용하는 초기화는 할당연산자(assignment operator)가 아닌 복사생성자(copy constructor)를 호출한다.


Read more

auto in C++

C++ auto 키워드에 대해서
Effective Modern C++ Chapter 2.


auto vs implicit type

변수 초기화

auto는 변수의 선언과 동시에 초기화를 강제할 수 있다.

1
2
3
4
int x;      // 선언되었지만 초기화되지 않음.

auto x; // error!
auto x = 0; // OK. 선언과 동시에 초기화 됨

Read more