Usi*_*Cpp 15 c++ templates member-function-pointers type-traits c++11
我想拥有类型特征,这将有助于我从成员函数指针中获取类的类型。我调查了这个答案 ,发现我已经达到目标了。
看起来像这样:
#include <iostream>
// example class
struct MyClass {
void funct() { std::cout << "funct has been called....\n"; }
};
// traits
template<typename Class> struct get_class{};
template<typename ReType, typename Class, typename... Args>
struct get_class<ReType(Class::*)(Args...)>
{
using type = Class;
};
template<typename Type> using get_class_t = typename get_class<Type>::type;
int main()
{
get_class_t<decltype(&MyClass::funct)> myObj;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---> this is a lot of typing
myObj.funct();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,如代码中所示,我每次都需要编写,get_class_t<decltype(&MyClass::funct)>
或者
auto ptr = &MyClass::funct;
get_class_t<decltype(ptr)> myObj;
// ^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
这很多decltype()。我想写
class_t<ptr> obj;
or
class_t<&MyClass::funct> myObj;
Run Code Online (Sandbox Code Playgroud)
比较方便
我做了以下函数,它将返回该类的结果对象,也许我可以做,只要我想要。
template<typename Type>
auto helper_function(Type ptr)->get_class_t<Type>
{
return get_class_t<Type>{};
}
template<typename Type>
using class_t = /* decltype(helper_function(Type ptr));*/
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // what could be here?
Run Code Online (Sandbox Code Playgroud)
我不知道该如何完成。我的目标是以某种方式扩展特征,以便可以创建类似
auto ptr = &MyClass::funct;
class_t<ptr> myObj;
// or
class_t<&MyClass::funct> myObj;
Run Code Online (Sandbox Code Playgroud)
还有其他方法吗?还是我应该坚持学习decltype()?
正如我所标记的,我想看看C ++ 11是否可能?
Lig*_*ica 11
(为将来的访问者存档了答案;此解决方案需要C ++ 17!)
你真的很亲密!
诀窍是auto模板参数,以及指向成员的指针可以用作模板参数的事实,如下所示:
template <auto thing>
using class_t = get_class_t<decltype(thing)>;
int main()
{
class_t<&MyClass::funct> myObj;
myObj.funct();
}
Run Code Online (Sandbox Code Playgroud)
当然,如果您可以编写此代码,那么您已经知道类型,因此只需编写即可MyClass,因此并不是很有用。
可悲的是,您将无法使其接受ptr为模板参数。你get_class_t为此坚持:
int main()
{
auto ptr = &MyClass::funct;
get_class_t<decltype(ptr)> myObj;
myObj.funct();
}
Run Code Online (Sandbox Code Playgroud)
在后一种情况下,好的类型别名可以为您提供一些帮助:
auto ptr = &MyClass::funct;
using ClassType = get_class_t<decltype(ptr)>;
ClassType myObj;
myObj.funct();
Run Code Online (Sandbox Code Playgroud)
我个人认为这种详细程度是相当合理的。
您可以提供一个将创建所需对象的函数。这很容易实现:
template<typename T, typename ...Args>
auto makeObjectForMethod(T&&, Args&& ...args) -> get_class_t<decltype(&MyClass::funct)>
{
using R = get_class_t<decltype(&MyClass::funct)>;
return R{ std::forward(args)... };
}
int main()
{
auto myObj = makeObjectForMethod(&MyClass::funct);
myObj.funct();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
可与C ++ 11一起使用并且非常方便:https : //wandbox.org/permlink/usMa3fA0I2HCNJ7M
唯一的缺点是,对于类字段,它不是很有帮助。