본문 바로가기
프로그래밍/C || CPP

[C++] 키워드 constexpr 알아보기

by _BlankSpace 2018. 4. 23.

1. constexpr이란. (const와의 차이점..)


먼저, 키워드 constexpr은 c++11에서 처음 도입되어, c++14에서 향상되었다.


해당 키워드는 const와 비슷하면서도 다르다고 할 수 있다.

(당연히, 그러니까 const가 있어도 새롭게 나온 거겠지만..)


기존의 const는 const로 지정한 변수의 값을 수정하려고 할 때, 컴파일러 오류를 발생하도록 한다.

반면에 constexpr도 지정한 변수의 값을 수정하려 할 때 오류를 발생시키지만 컴파일 타임에 오류를 발생 시킨다.

즉, const는 런타임에 오류를 확인하는 것이고, constexpr은 컴파일을 할 때 오류를 확인할 수 있는 것이다.


그래서 그런지, 요즘은 constexpr을 더 이용하라고 하는 편인듯?? 물론 c++11 이후의 코드에 적용이겠지만..

허나, 단점도 있으니, 컴파일 속도가 느려진다는 점이다. 그래도 런타임에서 에러 확인하는 것보다는 낫겠지?


여튼, 이러한 constexpr의 사용으로 인해서 다음과 같은 코드도 사용 가능하다.


1
2
3
4
5
6
7
// 1
constexpr int _arraySize = 3;
std::array<int, _arraySize> tmp;
 
// 2
const int _arraySize = 5;
std::array<int, _arraySize> tmp;
cs

1번은 constexpr 키워드를 사용하였고, 2번은 const 키워드를 사용하였다.

이러한 키워드 차이는 3, 7번 라인에서 결과로 확인할 수 있다.


먼저, 3번 라인은 에러가 없는 코드이다. 그 이유는 constexpr을 사용하여, 컴파일 시간에 _arraySize를 확인할 수 있기 때문이다.

반면에 7번 라인처럼 const를 이용한다면 에러가 발생한다.

이 두 가지 예제가 차이라고 할 수 있다.


따라서, constexpr과 const의 주요 차이점은 변수의 초기화 시점이라고 할 수 있겠다.


2. constexpr 변수


변수가 리터럴타입이고 초기화 된 상태라면, constexpr로 선언할 수 있다.

또한, 초기화가 생성자에 의해서 실행되는 것이라면 생성자도 constexpr로 선언되어야 한다.


참조되는 객체가 상수 표현식에 의해서 초기화되고, 초기화 중에 호출되는 암시적 변환이 상수 표현식이라면

해당 참조는 constexpr로 선언될 수 있다.


constexpr의 모든 선언은 당연히 constexpr 지정자가 있어야 된다.


다음 사용 예를 보자.

1
2
3
4
5
6
constexpr float x = 3.0;
constexpr float y{5};
constexpr float z = exp(12);
constexpr int i; // Error! Not initialized
int j = 0;
constexpr int k = j + 1//Error! j not a constant expression
cs

4번 줄처럼 초기화를 하지 않으면 에러가 발생한다.

또한, 6번 줄처럼 새로운 값을 지정하려고 하면, 에러가 발생한다.


3. constexpr 함수


constexpr 함수는 컴파일 시 반환 값을 계산할 수 있다.


1
constexpr int nameSize() { return 5; }
cs

위의 예처럼, 반환 값을 컴파일할 때 확인할 수 있다.


constexpr은 다음 규칙이 적용된다.

1. constexpr 함수는 오직 literal type을 반환해야 한다.

2. constexpr은 재귀적일 수 있다.

3. virtual 키워드는 불가능 하다. 생성자가 virtual 베이스의 클래스를 가진 클래스라면 constexpr을 사용할 수 없다.

4. body는 = default 또는 = delete로 정의될 수 있다. (뭔소리인가..? 나는 누구인가? 나중에 이해하면 고치자..)

5. body에 goto문 또는 try 블록을 포함할 수 없다.

등등..


1
2
3
4
5
6
constexpr float exp(float x, int n)
{
    return n == 0 ? 1 :
        n % 2 == 0 ? exp(x * x, n / 2) :
        exp(x * x, (n - 1/ 2* x;
};
cs

위의 코드는 마이크로소프트에서 가져온 것인데, constexpr을 재귀적으로 사용할 때의 예제를 보여주고자 함인 것 같다.

위처럼 사용할 수 있다는 것만 이해하면 될 것 같다.


자세한 내용은 https://docs.microsoft.com/ko-kr/cpp/cpp/constexpr-cpp 을 참고하시기 바랍니다.


궁금한 점이 있으신 분은 댓글 남겨주시면 감사하겠습니다 :)

댓글