nullptr — 널 포인터 리터럴
nullptr — 널 포인터 리터럴 (C++11)
C++11 전에는 널 포인터를 나타내려고 매크로 NULL이나 정수 0을 썼어요. 그런데 0은 정수라서 함수 오버로딩에서 모호해지는 경우가 생기곤 했죠. C++11부터는 이런 문제를 깔끔하게 해결하는 전용 리터럴이 생겼어요. 바로 nullptr이에요.
본문
구문
nullptr
설명 (Explanation)
키워드 nullptr은 널 포인터 리터럴을 나타내요. 타입은 std::nullptr_t인 prvalue예요. nullptr에서 어떤 포인터 타입의 널 포인터 값, 어떤 멤버 포인터 타입으론 암시적 변환이 존재해요. 널 포인터 상수(null pointer constant)에도 비슷한 변환들이 있는데, 널 포인터 상수에는 std::nullptr_t 타입의 값뿐 아니라 매크로 NULL도 포함돼요.
즉 nullptr은 언어에 내장된 진짜 리터럴이고, std::nullptr_t라는 고유한 타입을 가져서 정수와 혼동될 일이 없어요.
키워드
nullptr
예제
nullptr이 더 이상 리터럴이 아니게 되더라도 널 포인터 상수로서의 의미를 유지한다는 걸 보여주는 예제예요.
#include <cstddef>
#include <iostream>
template<class T>
constexpr T clone(const T& t)
{
return t;
}
void g(int*)
{
std::cout << "Function g called\n";
}
int main()
{
g(nullptr); // Fine
g(NULL); // Fine
g(0); // Fine
g(clone(nullptr)); // Fine
// g(clone(NULL)); // ERROR: non-literal zero cannot be a null pointer constant
// g(clone(0)); // ERROR: non-literal zero cannot be a null pointer constant
}
출력:
Function g called
Function g called
Function g called
Function g called
nullptr은 타입이 std::nullptr_t인 진짜 상수이기 때문에 clone(nullptr)처럼 상수 표현식으로 전달해도 널 포인터 상수 의미를 그대로 가져요. 반면 NULL이나 0은 이 맥락에서 널 포인터 상수가 될 수 없어서 컴파일 오류가 나요.
표준 문서 (References)
- C++23 표준 (ISO/IEC 14882:2024) — 7.3.12 Pointer conversions [conv.ptr]
- C++20 표준 (ISO/IEC 14882:2020) — 7.3.12 Pointer conversions [conv.ptr]
- C++17 표준 (ISO/IEC 14882:2017) — 7.11 Pointer conversions [conv.ptr]
- C++14 표준 (ISO/IEC 14882:2014) — 4.10 Pointer conversions [conv.ptr]
- C++11 표준 (ISO/IEC 14882:2011) — 4.10 Pointer conversions [conv.ptr]
더 알아보기 (Learn more)
NULL— 구현 정의된 널 포인터 상수 매크로예요.std::nullptr_t— 널 포인터 리터럴nullptr의 타입이에요.typedef로 정의되어 있어요.