나는 Cppcon14에서 Walter Brown이 SFINAE 기술 을 발표 한 최신 템플릿 프로그래밍 ( Part I , Part II ) 에 대해 이야기하는 것을 보았다 void_t
.
예 : 모든 템플릿 인수가
올바른지 평가하는 간단한 변수 템플릿이 제공됩니다 void
.
template< class ... > using void_t = void;
그리고 member라는 멤버 변수가 있는지 확인하는 다음 특성 :
template< class , class = void >
struct has_member : std::false_type
{ };
// specialized as has_member< T , void > or discarded (sfinae)
template< class T >
struct has_member< T , void_t< decltype( T::member ) > > : std::true_type
{ };
나는 왜 그리고 어떻게 작동하는지 이해하려고 노력했다. 따라서 작은 예 :
class A {
public:
int member;
};
class B {
};
static_assert( has_member< A >::value , "A" );
static_assert( has_member< B >::value , "B" );
1. has_member< A >
has_member< A , void_t< decltype( A::member ) > >
A::member
존재decltype( A::member )
잘 구성되어있다void_t<>
유효하고 평가void
has_member< A , void >
따라서 전문화 된 템플릿을 선택합니다has_member< T , void >
평가true_type
2. has_member< B >
has_member< B , void_t< decltype( B::member ) > >
B::member
존재하지 않는다decltype( B::member )
잘못 형성되어 자동으로 실패 (정사각형)has_member< B , expression-sfinae >
이 템플릿은 삭제됩니다
- 컴파일러는
has_member< B , class = void >
void를 기본 인수로 찾습니다. has_member< B >
~에 평가하다false_type
질문 :
1. 이것에 대한 나의 이해가 맞습니까?
2. Walter Brown은 기본 인수가 void_t
작동하기 위해 사용 된 것과 동일한 유형이어야한다고 말합니다 . 왜 그런 겁니까? (이 유형이 왜 일치 해야하는지 알지 못합니다. 기본 유형만이 작동하지 않습니까?)
has_member< T , class = void >
기본 설정 이 필요하지 않습니다 void
. 이 특성이 언제든지 하나의 템플리트 인수와 함께 사용된다고 가정하면 기본 인수는 모든 유형이 될 수 있습니까?
template <class, class = void>
되었습니다 template <class, class = void_t<>>
. 이제 우리는 void_t
별칭 템플릿 구현으로 원하는 것을 자유롭게 할 수 있습니다 :)
has_member<A,int>::value
. 그런 다음 평가 된 부분 전문화가has_member<A,void>
일치하지 않습니다. 따라서has_member<A,void>::value
구문 설탕 인 경우 type의 기본 인수 여야 합니다void
.