그래서 다음과 같은 템플릿 유형 목록이 있습니다.
template <typename... Types>
struct type_list
{
};
다음과 같은 접근 자 기능을 만들었습니다.
template<class TypeList, size_t ElementIndex>
struct at;
template <template<typename...> class TypeList, typename Head, typename... OtherTypes, size_t ElementIndex>
struct at< TypeList<Head, OtherTypes...>, ElementIndex>
{
static_assert(ElementIndex < (size_v< TypeList<Head, OtherTypes...> >), "at_t : ElementIndex is bigger than list size");
using type = if_else_t < ElementIndex == 0, Head, typename at< TypeList<OtherTypes...>, ElementIndex - 1 >::type >;
};
template <template<typename...> class TypeList, typename Last, size_t ElementIndex>
struct at< TypeList<Last>, ElementIndex>
{
static_assert(ElementIndex < (size_v< TypeList<Last> >), "at_t : ElementIndex is bigger than list size");
using type = Last;
};
template<class TypeList, size_t ElementIndex>
using at_t = typename at<TypeList, ElementIndex>::type;
는 if_else_t<>
다음과 같은 구현이 :
template<bool Condition, typename True, typename False>
struct if_else
{
using type = True;
};
template<typename True, typename False>
struct if_else<false, True, False>
{
using type = False;
};
이제 다음을 사용하여 함수를 테스트하면
static_assert(std::is_same_v< bool, at_t< type_list<int, float, bool, char>, 2 > >, "at_t : Bad result");
ElementIndex가 목록 크기보다 큰지 확인하는 static_assert를 트리거합니다. 컴파일러의 출력에서 at<>
ElementIndex가 수치 제한 (ElementIndex = 0-1 인 경우)에 도달하고 static_assert가 트리거 될 때까지 절대 재귀를 중지하지 않음을 분명히 알 수 있습니다 .
내가 도대체 뭘 잘못하고있는 겁니까 ?
이상적인 대답은 또한 더 좋고, 더 우아하고, 구현해야합니다. at<>
:)
MSVC 및 C ++ 17을 사용하고 있습니다.
문제는 다음과 같은 경우입니다.
if_else_t < ElementIndex == 0, Head, typename at< TypeList<OtherTypes...>, ElementIndex - 1 >::type >;
하더라도 ElementIndex
이고 0
, 다른 두 종류의 증류기에 보내 것으로 평가되어야한다 if_else_t
(따라서 트리거 static_assert
).
대신 전문화를 사용하여 수정합니다.
template<class TypeList, size_t ElementIndex>
struct at;
template <template<typename...> class TypeList, typename Head, typename... OtherTypes>
struct at< TypeList<Head, OtherTypes...>, 0>
{
using type = Head;
};
template <template<typename...> class TypeList, typename Head, typename... OtherTypes, size_t ElementIndex>
struct at< TypeList<Head, OtherTypes...>, ElementIndex>
{
static_assert(ElementIndex < (size_v< TypeList<Head, OtherTypes...> >), "at_t : ElementIndex is bigger than list size");
using type = typename at< TypeList<OtherTypes...>, ElementIndex - 1 >::type;
};
template <template<typename...> class TypeList, size_t ElementIndex>
struct at< TypeList<>, ElementIndex>
{
static_assert(ElementIndex != ElementIndex, "at_t : ElementIndex is bigger than list size");
};
또는 표준을 사용할 수 있습니다. tuple_element
template<class TypeList, size_t ElementIndex>
struct at;
template <template<typename...> class TypeList, typename... Types, size_t ElementIndex>
struct at< TypeList<Types...>, ElementIndex>
{
static_assert(ElementIndex < (sizeof...(Types)), "at_t : ElementIndex is bigger than list size");
using type = std::tuple_element_t<ElementIndex, std::tuple<Types...>>;
};
참고 if_else_t
로 그냥std::conditional_t
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다