https://en.cppreference.com/w/cpp/concepts
modern c++이 된 C++11 에서는 template meta programming을 위하여 enable_if 가 사용되었고, c++17에서는 if constexpr이 이것을 도와주었다.
C++20에서는 Concepts 이라는 개념이 도입되며 template meta programming을 좀 더 편하게, 좀 더 안전하게 사용할 수 있게 되었다.
사용법은 다음과 같다.
template <typename T>
concept myConcept = /*조건*/;
이렇게 내가 원하는 조건을 지정해 두고 해당 concept을 template에 작성하면 된다.
include <iostream>
#include <type_traits>
template <typename T>
typename std::enable_if_t<std::is_same_v<T, int>, void>
print(T t)
{
std::cout << "print : " << t << std::endl;
}
int main()
{
print(42);
// print("Hello, world!"); // 컴파일 에러!
return 0;
}
예시로, 위와 같은 코드가 있다고 하자.
print를 하는 코드이다. 다만 type int 일 때만 사용 가능하다. 해당 코드를 concept을 이용하여 다시 구현하면
#include <iostream>
template <typename T>
concept SameAsInt = std::is_same_v<T, int>;
template <SameAsInt T>
void print(T t)
{
std::cout << "print : " << t << std::endl;
}
int main()
{
print(42);
// print("Hello, world!"); // 컴파일 에러!
return 0;
}
이런 식으로 구현이 가능하다.
변수를 정하듯 template T의 조건을 미리 지정할 수 있고, 해당 조건을 원하는 곳에서 쉽게 사용이 가능하다.
또, concept과 requires를 이용하여 조금 더 다양한 일도 할 수 있다.
template <typename T>
concept printable = requires(T obj) {
{obj.print()} -> std::convertible_to<void>;
};
printable 이라는 concept은 obj.print() 를 void type으로 암시적으로 변환시킬 수 있다. 라는 뜻이다.
이것을 잘 생각해 보면, obj라는 객체가 있고, 해당 객체가 print라는 함수를 수행한 결과가 void면 이 조건을 만족시킨다.
즉, obj가 void type의 print 함수를 가지고 있냐 없냐를 검사하는 concept이다!
#include <iostream>
template <typename T>
concept printable = requires(T obj) {
{obj.print()} -> std::convertible_to<void>;
};
template <printable T>
void printclass(T obj) {
obj.print();
}
class Aclass {
public:
void print() {
}
};
class Bclass {
public:
int nothing() {
}
};
int main()
{
Aclass a;
Bclass b;
printclass(a);
printclass(b); // error!
return 0;
}
위의 concept을 사용하여, 쉽게 print 함수를 가지고 있는 class만 인자로 받는 printclass 함수를 만들 수 있다.
'C++ > STL' 카테고리의 다른 글
[C++] Priority_queue (0) | 2023.06.04 |
---|---|
[C++17] Optional (0) | 2023.05.28 |
[C++] std::async. launch policy (0) | 2023.04.20 |
[C++] std::async, std::thread (2) (0) | 2023.04.10 |
[C++] std::async, std::thread (1) (0) | 2023.04.09 |