[C++20] 템플릿에서 Non-Type 인자 받기 (Non-Type Template Parameter)
템플릿에서 Non-Type 인자 받기 (Non-Type Template Parameter)
Non-Type Template Parameter란?
Non-Type Template Parameter(NTTP)는 템플릿에서 타입이 아닌 값을 매개변수로 받는 기능이다.
C++20 이전에는 정수형, 포인터, 열거형 등 제한된 타입만 사용할 수 있었지만,
C++20부터는 구조적 타입(structural type)도 사용할 수 있게 되었다.
기존의 템플릿에서 Non-Type 사용 (C++20 이전)
Non-Type
- int, enum
- 포인터, 참조
- nullptr_t
// typename 대신에 Non-Type이 들어갈 수 있다.
template<typename T>
예시코드
template<double d>
auto GetDouble()
{
return d;
}
int main()
{
auto d1 = GetDouble<5.5>();
// 아래의 두 개는 같지만 밑에 것은 바운더리를 벗어났을 경우 체크해 잡아줄 수 있다.
int arr[5];
std::array<int, 5> arr; // int는 런타임 파라미터
}
struct ClassType
{
// 리터럴 타입(literal type) 만들기
// 컴파일 타임에 확정, 만약에 constexpr를 떼면 아래의 GetClassType<ClassType(2021)>()부분에서 컴파일되지 않는다.
constexpr ClassType(int) { }
};
template<int N>
struct IntToType
{
enum { value = N };
};
template<ClassType c>
auto GetClassType()
{
return c;
}
int main()
{
auto c1 = GetClassType<ClassType(2021)>();
}
템플릿에서 Non-Type 인자 받기 (C++20)
구조적 타입(structural type) 인자 받기
#include <iostream>
using namespace std;
#include <array>
template<int N>
class StringLiteral
{
public:
constexpr StringLiteral(char const (&str)[N])
{
std::copy(str, str+N, _data);
}
char _data[N];
};
template<StringLiteral str> // Non-Type인자 StringLiteral를 받아준다.
class ClassTemplate { };
template<StringLiteral str>
void FunctionTemplate()
{
cout << str._data << endl;
}
int main()
{
ClassTemplate<"Hello World"> cls1;
FunctionTemplate<"Hello World">();
}
주의사항: std::string은 Non-Type Template Parameter로 사용이 불가능하다!
std::string은 런타임에 동적으로 할당되는 리소스를 관리하므로 Non-Type Template Parameter로 사용할 수 없다.
대신, 컴파일 타임에 고정된 문자열을 표현하는 구조적 타입을 만들어 사용할 수 있다.
template<std::size_t N>
struct FixedString
{
char value[N];
constexpr FixedString(const char (&str)[N])
{
for (std::size_t i = 0; i < N; ++i)
{
value[i] = str[i];
}
}
};
template<FixedString fs>
void print_fixed_string()
{
std::cout << fs.value << '\n';
}
int main()
{
print_fixed_string<FixedString("Hello, World!")>();
}
왜 Non-Type Template Parameter를 사용할까?
Compile-Time Regular Expression(정규 표현식)은 런타임에 동작한다.
- std::regex 같은건 런타임 동작
정규 표현식 패턴을 컴파일 타임에 안다면, 굳이 런타임까지 갈 필요 없다! (런타임까지 갈 필요가 없는 경우가 생길 수 있다)
컴파일 타임에 해결이 가능하다!
Non-Type Template Parameter(NTTP)의 활용 사례
- 컴파일 타임에 결정되는 상수 값을 템플릿 인자로 전달할 때
- 정적 배열의 크기나 반복 횟수 등을 템플릿 인자로 지정할 때
- 컴파일 타임에 정규 표현식이나 파서를 생성할 때
- 형식 안전성을 강화하고 코드의 재사용성을 높일 때
'⭐ Programming > C++20' 카테고리의 다른 글
[C++20] erase, erase_if, contains, starts_with, ends_with (0) | 2025.06.29 |
---|---|
[C++20] Ranged-Based for with Initializer (0) | 2025.05.25 |
[C++20] 어트리트뷰트 (Attribute) (0) | 2025.05.25 |
[C++20] 람다에서의 템플릿 매개변수 (Template Parameter for Lambda) (0) | 2025.05.25 |
[C++ 20] Concept (0) | 2025.04.30 |
댓글
이 글 공유하기
다른 글
-
[C++20] Ranged-Based for with Initializer
[C++20] Ranged-Based for with Initializer
2025.05.25 -
[C++20] 어트리트뷰트 (Attribute)
[C++20] 어트리트뷰트 (Attribute)
2025.05.25 -
[C++20] 람다에서의 템플릿 매개변수 (Template Parameter for Lambda)
[C++20] 람다에서의 템플릿 매개변수 (Template Parameter for Lambda)
2025.05.25 -
[C++ 20] Concept
[C++ 20] Concept
2025.04.30