我可以获得成员函数模板参数的拥有对象吗?
Can I get the Owning Object of a Member Function Template Parameter?
给定一个对象:
struct foo {
void func();
};
现在给定模板化函数声明:
template<typename T, T F>
void bar();
所以 bar
将采用这样的成员函数:
bar<decltype(&foo::func), &foo::func>()
在 bar
的正文中,我想从 T
恢复类型 foo
。我可以这样做吗?我希望能够做这样的事情:
get_obj<T> myfoo;
(myfoo.*F)();
我知道 get_obj
不是东西,但是有没有办法写它?
如果限制为 void(T::mem_fun)()
:
#include <iostream>
struct foo {
void func(){ std::cout << "foo"; }
};
template <typename T> struct get_type;
template <typename T> struct get_type<void(T::*)()> {
using type = T;
};
template <typename T> using get_type_t = typename get_type<T>::type;
template<typename T, T F> void bar(){
get_type_t<T> myfoo;
(myfoo.*F)();
}
int main () {
bar<decltype(&foo::func), &foo::func>();
}
template<class T>
struct get_memfun_class;
template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...)> {
using type=T;
};
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
template<auto M>
using class_of_memfun = get_memfun_class_t< decltype(M) >;
class_of_memfun<F>
就是成员函数 F
.
的 class
要处理 const/volatile/etc 你最终不得不做一堆版本。这很烦人。这是一个例子:
template<class T>
struct get_memfun_class;
#define GET_MEMFUN_CLASS(...) \
template<class R, class T, class...Args> \
struct get_memfun_class<R(T::*)(Args...) __VA_ARGS__> { \
using type=T; \
}
可能你想要:
template<class R, class T, class...Args> \
struct get_memfun_class<R(T::*)(Args...) __VA_ARGS__> { \
using type=T __VA_ARGS__; \
}
指向 const memfun 的指针的 class 类型是否为 const class?
选好后,需要写24次上述宏的用法:
GET_MEMFUN_CLASS();
GET_MEMFUN_CLASS(const);
GET_MEMFUN_CLASS(volatile);
GET_MEMFUN_CLASS(const volatile);
GET_MEMFUN_CLASS(&);
GET_MEMFUN_CLASS(const&);
GET_MEMFUN_CLASS(volatile&);
GET_MEMFUN_CLASS(const volatile&);
GET_MEMFUN_CLASS(&&);
GET_MEMFUN_CLASS(const&&);
GET_MEMFUN_CLASS(volatile&&);
GET_MEMFUN_CLASS(const volatile&&);
GET_MEMFUN_CLASS(noexcept);
GET_MEMFUN_CLASS(const noexcept);
GET_MEMFUN_CLASS(volatile noexcept);
GET_MEMFUN_CLASS(const volatile noexcept);
GET_MEMFUN_CLASS(& noexcept);
GET_MEMFUN_CLASS(const& noexcept);
GET_MEMFUN_CLASS(volatile& noexcept);
GET_MEMFUN_CLASS(const volatile& noexcept);
GET_MEMFUN_CLASS(&& noexcept);
GET_MEMFUN_CLASS(const&& noexcept);
GET_MEMFUN_CLASS(volatile&& noexcept);
GET_MEMFUN_CLASS(const volatile&& noexcept);
#undef GET_MEMFUN_CLASS
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
我不知道有什么方法可以避免完成所有 24 个专业化以实现全面覆盖。如果您认为这很愚蠢,那您是对的;请随时通过向 C++ 标准委员会提出修复建议来表达您的烦恼。
如果您为多个特征做这样的事情,您可以在一处写下 "strip lvalue, rvalue, noexcept and cv qualifiers" 部分,然后将它们分段传递。
给定一个对象:
struct foo {
void func();
};
现在给定模板化函数声明:
template<typename T, T F>
void bar();
所以 bar
将采用这样的成员函数:
bar<decltype(&foo::func), &foo::func>()
在 bar
的正文中,我想从 T
恢复类型 foo
。我可以这样做吗?我希望能够做这样的事情:
get_obj<T> myfoo;
(myfoo.*F)();
我知道 get_obj
不是东西,但是有没有办法写它?
如果限制为 void(T::mem_fun)()
:
#include <iostream>
struct foo {
void func(){ std::cout << "foo"; }
};
template <typename T> struct get_type;
template <typename T> struct get_type<void(T::*)()> {
using type = T;
};
template <typename T> using get_type_t = typename get_type<T>::type;
template<typename T, T F> void bar(){
get_type_t<T> myfoo;
(myfoo.*F)();
}
int main () {
bar<decltype(&foo::func), &foo::func>();
}
template<class T>
struct get_memfun_class;
template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...)> {
using type=T;
};
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
template<auto M>
using class_of_memfun = get_memfun_class_t< decltype(M) >;
class_of_memfun<F>
就是成员函数 F
.
要处理 const/volatile/etc 你最终不得不做一堆版本。这很烦人。这是一个例子:
template<class T>
struct get_memfun_class;
#define GET_MEMFUN_CLASS(...) \
template<class R, class T, class...Args> \
struct get_memfun_class<R(T::*)(Args...) __VA_ARGS__> { \
using type=T; \
}
可能你想要:
template<class R, class T, class...Args> \
struct get_memfun_class<R(T::*)(Args...) __VA_ARGS__> { \
using type=T __VA_ARGS__; \
}
指向 const memfun 的指针的 class 类型是否为 const class?
选好后,需要写24次上述宏的用法:
GET_MEMFUN_CLASS();
GET_MEMFUN_CLASS(const);
GET_MEMFUN_CLASS(volatile);
GET_MEMFUN_CLASS(const volatile);
GET_MEMFUN_CLASS(&);
GET_MEMFUN_CLASS(const&);
GET_MEMFUN_CLASS(volatile&);
GET_MEMFUN_CLASS(const volatile&);
GET_MEMFUN_CLASS(&&);
GET_MEMFUN_CLASS(const&&);
GET_MEMFUN_CLASS(volatile&&);
GET_MEMFUN_CLASS(const volatile&&);
GET_MEMFUN_CLASS(noexcept);
GET_MEMFUN_CLASS(const noexcept);
GET_MEMFUN_CLASS(volatile noexcept);
GET_MEMFUN_CLASS(const volatile noexcept);
GET_MEMFUN_CLASS(& noexcept);
GET_MEMFUN_CLASS(const& noexcept);
GET_MEMFUN_CLASS(volatile& noexcept);
GET_MEMFUN_CLASS(const volatile& noexcept);
GET_MEMFUN_CLASS(&& noexcept);
GET_MEMFUN_CLASS(const&& noexcept);
GET_MEMFUN_CLASS(volatile&& noexcept);
GET_MEMFUN_CLASS(const volatile&& noexcept);
#undef GET_MEMFUN_CLASS
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
我不知道有什么方法可以避免完成所有 24 个专业化以实现全面覆盖。如果您认为这很愚蠢,那您是对的;请随时通过向 C++ 标准委员会提出修复建议来表达您的烦恼。
如果您为多个特征做这样的事情,您可以在一处写下 "strip lvalue, rvalue, noexcept and cv qualifiers" 部分,然后将它们分段传递。