types_add_pointer
types_add_pointer (포인터 추가)
std::add_pointer는 주어진 타입에 포인터를 추가하는 C++ 타입 특성(type trait)이에요. 참조 타입을 처리할 때는 참조 대상 타입을 가리키는 포인터를 만들고, cv 또는 ref 한정 함수 타입은 그대로 유지해요. 이 도구는 템플릿 메타프로그래밍에서 타입 변환을 깔끔하게 표현할 때 유용해요.
출처: cppreference
본문
<type_traits> 헤더에 정의되어 있어요. C++11부터 사용할 수 있어요.
T가 참조 타입이라면, 멤버 typedeftype은 참조되는 타입을 가리키는 포인터가 돼요.- 그렇지 않고
T가 객체 타입, cv 또는 ref 한정이 없는 함수 타입, 또는 (cv 한정일 수 있는)void타입이라면, 멤버 typedeftype은T*타입이 돼요. - 그 외의 경우(
T가 cv 또는 ref 한정 함수 타입이라면), 멤버 typedeftype은T타입 그대로예요. - 프로그램이
std::add_pointer에 특수화를 추가하면 동작이 정의되지 않아요.
멤버 타입 (Member types)
| 이름 | 설명 |
|---|---|
type |
T 또는 T가 참조하는 타입을 가리키는 포인터 |
헬퍼 타입 (Helper types)
C++14부터 다음 별칭 템플릿을 사용할 수 있어요.
template < class T > using add_pointer_t = typename add_pointer < T >:: type ;
가능한 구현 (Possible implementation)
namespace detail { template < class T > struct type_identity { using type = T ; }; // or use std::type_identity (since C++20) template < class T > auto try_add_pointer ( int ) -> type_identity < typename std :: remove_reference < T >:: type *> ; // usual case template < class T > auto try_add_pointer (...) -> type_identity < T > ; // unusual case (cannot form std::remove_reference<T>::type*) } // namespace detail template < class T > struct add_pointer : decltype ( detail :: try_add_pointer < T > ( 0 )) {};
예제 (Example)
#include <iostream>
#include <type_traits>
template<typename F, typename Class>
void ptr_to_member_func_cvref_test(F Class::*)
{
// F is an "abominable function type"
using FF = std::add_pointer_t<F>;
static_assert(std::is_same_v<F, FF>, "FF should be precisely F");
}
struct S
{
void f_ref() & {}
void f_const() const {}
};
int main()
{
int i = 123;
int& ri = i;
typedef std::add_pointer<decltype(i)>::type IntPtr;
typedef std::add_pointer<decltype(ri)>::type IntPtr2;
IntPtr pi = &i;
std::cout << "i = " << i << '\n';
std::cout << "*pi = " << *pi << '\n';
static_assert(std::is_pointer_v<IntPtr>, "IntPtr should be a pointer");
static_assert(std::is_same_v<IntPtr, int*>, "IntPtr should be a pointer to int");
static_assert(std::is_same_v<IntPtr2, IntPtr>, "IntPtr2 should be equal to IntPtr");
typedef std::remove_pointer<IntPtr>::type IntAgain;
IntAgain j = i;
std::cout << "j = " << j << '\n';
static_assert(!std::is_pointer_v<IntAgain>, "IntAgain should not be a pointer");
static_assert(std::is_same_v<IntAgain, int>, "IntAgain should be equal to int");
ptr_to_member_func_cvref_test(&S::f_ref);
ptr_to_member_func_cvref_test(&S::f_const);
}
출력:
i = 123
*pi = 123
j = 123
결함 보고 (Defect reports)
다음 동작 변경 결함 보고는 이전에 발표된 C++ 표준에 소급 적용되었어요.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| LWG 2101 | C++11 | std::add_pointer는 cv/ref 한정 함수 타입에 대한 포인터를 생성해야 했어요. |
cv/ref 한정 함수 타입 자체를 생성해요. |
같이 보기 (See also)
is_pointer (C++11) |
타입이 포인터 타입인지 확인해요 (클래스 템플릿) |
|---|---|
remove_pointer (C++11) |
주어진 타입에서 포인터를 제거해요 (클래스 템플릿) |
add_pointer (C++26) |
반영된 타입에 포인터를 추가해요 (함수) |