회원 유형의 존재를 감지하는 또 다른 방법은 void_t
을 사용하는 것입니다. 유효한 부분 특수화는 기본 매개 변수와 일치하는 한 일반 구현보다 바람직하기 때문에 유효 할 때 void
으로 평가되는 유형이 필요하며 지정된 구성원이있을 때만 유효합니다. 이 유형은 일반적으로 void_t
으로 알려진 (C++ 17 기준, 정식 적으로)입니다. 컴파일러가 제대로 지원하지 않는 경우
template<class...>
using void_t = void;
이 (초기 C++ 14 컴파일러에서, 별명 템플릿에서 사용되지 않는 매개 변수는 위의 void_t
파괴, SFINAE을 보장하기 위해 보장되지 않은), 해결 방법을 사용할 수 있습니다. C++ 17로
template<typename... Ts> struct make_void { typedef void type; };
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
,
void_t
는
type_traits
에서, 유틸리티 라이브러리에서 사용할 수 있습니다.
#include <iostream>
#include <vector>
#include <type_traits> // For void_t.
template<class T, class V = void>
struct Functor {
void operator()() const {
std::cerr << "general" << std::endl;
}
};
// Use void_t here.
template<class T>
struct Functor<T, std::void_t<typename T::Vec>> {
void operator()() const {
std::cerr << "special" << std::endl;
}
};
struct Foo {
typedef std::vector<int> Vec;
};
int main() {
Functor<Foo> ac;
ac();
}
이와 같이 출력은 의도 한대로 special
입니다.
이 경우 회원 유형의 존재 여부를 확인하기 때문에 매우 간단합니다. 표현 SFINAE 또는 type_traits
라이브러리없이 수행 할 수 있으므로 필요한 경우 C++ 03 기능을 사용하도록 검사를 다시 작성할 수 있습니다. 내 지식
// void_t:
// Place above Functor's definition.
template<typename T> struct void_t { typedef void type; };
// ...
template<class T>
struct Functor<T, typename void_t<typename T::Vec>::type> {
void operator()() const {
std::cerr << "special" << std::endl;
}
};
, 이것은 대부분의 전부는 아니지만, SFINAE 가능한 C++ 03, C++ 11-, C++ 14- 또는 C++ 1Z 호환 컴파일러 작동합니다 . 이것은 표준보다 조금 뒤처진 컴파일러를 다루거나, C++ 11 호환 컴파일러가 아직없는 플랫폼 용으로 컴파일 할 때 유용 할 수 있습니다.
void_t
에 대한 자세한 내용은 cppreference를 참조하십시오.
'compiler' 태그를 제거했습니다. 일반적으로 컴파일 프로세스 자체에 관한 질문에 사용되는 반면,이 질문은 C++ 언어에 관한 것입니다. –