나는 데이터 멤버와 포인터에 대한 멤버 함수 포인터를 가지고 놀고있다. 클래스의 타입과 함수의 리턴 타입 또는 타입을 사용하는 특수 std :: map을 생성 할 템플릿을 생성하려고한다. 데이터 회원.클래스 템플릿 전문화를 사용하여 별칭 템플릿의 전문화를 어떻게 만들 수 있습니까?
그래서 :
template<typename PMember>
using Index = std::map<typename return_type_of<PMember>, typename pod_type_of<PMember>>;
struct Foo { int x; char* get_name(); };
Index<decltype(&Foo::x)> indexOnX; // std::map<int, Foo>
Index<decltype(&Foo::get_name)> indexOnGetName; // std::map<char*, Foo>
나는 그렇게 2 별칭 템플릿을 작성하는 관리했지만, 슬프게도 그들은 다른 이름을 가지고있다. Code in Godbolt는 :
include <type_traits>
#include <map>
/**
* Splits a pointer to member function type into it's class and return type.
* This only works with member functions that take no arguments.
*/
template <typename MemFunc_t>
struct decompose_member_function_pointer {
// We hide the implementation within the details struct. These should not be used by users of the class.
struct details {
// This templated function will be used to split M into it's component parts.
template <typename C, typename T>
static T get_returntype(T (C::*v)());
template <typename C, typename T>
static C get_classtype(T (C::*v)());
};
using return_type = decltype(details::get_returntype(std::declval<std::decay_t<MemFunc_t>>()));
using type = decltype(details::get_classtype(std::declval<std::decay_t<MemFunc_t>>()));
};
template <typename Member_t>
using decompose_member_function_pointer_t = typename decompose_member_function_pointer<Member_t>::type;
template <typename Member_t>
using decompose_member_function_pointer_rt = typename decompose_member_function_pointer<Member_t>::return_type;
template <typename Member_t>
struct decompose_member_object_pointer {
struct details {
template <typename C, typename T>
static T get_returntype(T C::*v);
template <typename C, typename T>
static C get_classtype(T C::*v);
};
using return_type = decltype(details::get_returntype(std::declval<Member_t>()));
using type = decltype(details::get_classtype(std::declval<Member_t>()));
};
template <typename Member_t>
using decompose_member_object_pointer_t = typename decompose_member_object_pointer<Member_t>::type;
template <typename Member_t>
using decompose_member_object_pointer_rt = typename decompose_member_object_pointer<Member_t>::return_type;
template<typename MemFunc, typename = std::enable_if_t<std::is_member_function_pointer_v<MemFunc>>>
using IndexOnMFP = std::map<
decompose_member_function_pointer_rt<MemFunc>,
decompose_member_function_pointer_t<MemFunc>>;
template<typename MemFunc, typename = std::enable_if_t<std::is_member_object_pointer_v<MemFunc>>>
using IndexOnMOP = std::map<
decompose_member_object_pointer_rt<MemFunc>,
decompose_member_object_pointer_t<MemFunc>>;
// Now try using these alias templates
struct MyClass
{
char value;
int age();
int age2() const;
};
IndexOnMOP<decltype(&MyClass::value)> indexOnValue;
IndexOnMFP<decltype(&MyClass::age)> indexOnAge;
내가 원하는 것은 하나의 템플릿 별칭, 예를 들어,에 IndexOnMOP 및 IndexOnMFP을 결합 할 수있다 IndexOnMemberPointer. 기능 및 클래스 템플릿 만 전문화 할 수 있다는 점에 감사드립니다. 지금까지 모든 시도가 실패했습니다.
후속 작업으로 포인터를 const 멤버 함수로 변환하는 작업을 지원할 수 있기를 바랍니다.
예 I가 필요 : 물론
당신이 좌우 스텝에게조차 할 수 있도록 decltype를,이, C++ 17 ret_type의 std :: conditional_t 버전을 사용하십시오. std :: invoke_result_t에서 모든 어려운 일이 일어나고 있다고 가정합니다. 코드는 const 멤버 함수에서도 작동합니다. 마지막으로, 이제 Foo에서 키를 추출하는 메소드를 작성하려고하므로 decltype을 단계별로 스테핑하는 것이 정확하게 수행하고 싶습니다. –
초보자에서 메타 프로그래밍에 이르기까지 필자가 몰랐던 패턴은 템플릿 형질 특성 클래스를 선언 한 다음 멤버 유형 및 클래스 유형에 템플릿을 사용하여 멤버에 대한 포인터에 대한 특성의 특성을 정의하는 것이 었습니다. 인덱스 별칭 템플릿을 인스턴스화하는 동안 C++ 17은 구성원에 대한 포인터를 개별 조각으로 확장하는 특성 서식 파일과 일치하는 항목을 찾습니다. –