如何通过扩展以下类型特征来删除 decltype(& MyClass::func) 部分?
How to remove decltype(&MyClass::funct) part by extending the following type traits?
我想要类型特征,这将帮助我获得 class 的类型
来自成员函数指针。我调查了
并找到了我的目标。
看起来像这样:
#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;
}
但是,如图所示的代码我需要每次都写get_class_t<decltype(&MyClass::funct)>
或者在
的情况下
auto ptr = &MyClass::funct;
get_class_t<decltype(ptr)> myObj;
// ^^^^^^^^^^^^^^
很多 decltype()
ing。我想改写
class_t<ptr> obj;
or
class_t<&MyClass::funct> myObj;
哪个更方便
我执行了以下函数,它将 return class 的结果对象
也许我可以做,我想做。
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?
我不知道如何完成这个。我的目标是以这样一种方式扩展特征
可以创建一个像
这样的对象
auto ptr = &MyClass::funct;
class_t<ptr> myObj;
// or
class_t<&MyClass::funct> myObj;
还有其他方法吗?还是我必须坚持 decltype()
ing?
正如我标记的那样,我想看看 C++11 是否可行?
(为未来的访问者存档答案;此解决方案需要 C++17!)
你真的很接近!
诀窍是 auto
模板参数,事实上 pointers-to-members 可以用作模板参数,如下所示:
template <auto thing>
using class_t = get_class_t<decltype(thing)>;
int main()
{
class_t<&MyClass::funct> myObj;
myObj.funct();
}
当然,如果你会写这个,那么你已经知道类型了,所以你只写MyClass
,所以这不是很有用。
遗憾的是,您无法让它接受 ptr
作为模板参数;你为此坚持 get_class_t
:
int main()
{
auto ptr = &MyClass::funct;
get_class_t<decltype(ptr)> myObj;
myObj.funct();
}
(live demo)
在后一种情况下,一个好的类型别名可以帮助你一点:
auto ptr = &MyClass::funct;
using ClassType = get_class_t<decltype(ptr)>;
ClassType myObj;
myObj.funct();
(live demo)
我个人认为这种冗长程度非常合理。
您可以提供一个函数来创建所需的对象。这个实现起来很简单:
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;
}
适用于 C++11,非常方便:
https://wandbox.org/permlink/usMa3fA0I2HCNJ7M
唯一的缺点是在 class 字段的情况下它不是很有帮助。
我想要类型特征,这将帮助我获得 class 的类型
来自成员函数指针。我调查了
看起来像这样:
#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;
}
但是,如图所示的代码我需要每次都写get_class_t<decltype(&MyClass::funct)>
或者在
auto ptr = &MyClass::funct;
get_class_t<decltype(ptr)> myObj;
// ^^^^^^^^^^^^^^
很多 decltype()
ing。我想改写
class_t<ptr> obj;
or
class_t<&MyClass::funct> myObj;
哪个更方便
我执行了以下函数,它将 return class 的结果对象 也许我可以做,我想做。
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?
我不知道如何完成这个。我的目标是以这样一种方式扩展特征 可以创建一个像
这样的对象auto ptr = &MyClass::funct;
class_t<ptr> myObj;
// or
class_t<&MyClass::funct> myObj;
还有其他方法吗?还是我必须坚持 decltype()
ing?
正如我标记的那样,我想看看 C++11 是否可行?
(为未来的访问者存档答案;此解决方案需要 C++17!)
你真的很接近!
诀窍是 auto
模板参数,事实上 pointers-to-members 可以用作模板参数,如下所示:
template <auto thing>
using class_t = get_class_t<decltype(thing)>;
int main()
{
class_t<&MyClass::funct> myObj;
myObj.funct();
}
当然,如果你会写这个,那么你已经知道类型了,所以你只写MyClass
,所以这不是很有用。
遗憾的是,您无法让它接受 ptr
作为模板参数;你为此坚持 get_class_t
:
int main()
{
auto ptr = &MyClass::funct;
get_class_t<decltype(ptr)> myObj;
myObj.funct();
}
(live demo)
在后一种情况下,一个好的类型别名可以帮助你一点:
auto ptr = &MyClass::funct;
using ClassType = get_class_t<decltype(ptr)>;
ClassType myObj;
myObj.funct();
(live demo)
我个人认为这种冗长程度非常合理。
您可以提供一个函数来创建所需的对象。这个实现起来很简单:
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;
}
适用于 C++11,非常方便: https://wandbox.org/permlink/usMa3fA0I2HCNJ7M
唯一的缺点是在 class 字段的情况下它不是很有帮助。