如何通过扩展以下类型特征来删除decltype(&MyClass :: funct)部分?

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)

现场演示

我个人认为这种详细程度是相当合理的。

  • @UsingCpp Dang,有人删除了该标签。抱歉。我会继续为后代保留这个答案,但我认为您当时不走运。 (2认同)

Mar*_*k R 8

您可以提供一个将创建所需对象的函数。这很容易实现:

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

唯一的缺点是,对于类字段,它不是很有帮助。