Deducing pointer-to-member template arguments

隐身守侯 提交于 2021-02-08 21:22:11

问题


Consider classes with member variables, like these:

struct A {
    int a;
    char b;
};

struct B {
    double c;
    bool d;
};

Is it possible to declare a template class that accepts as its template argument a pointer-to-member-object to any one of the members declared in the above classes? A class that accepts a generic pointer-to-member-object could be declared and used as follows:

template<typename Class, typename Type, Type (Class::*Member)>
struct Magic
{ };

// Usage:
typedef Magic<A, int, &A::a> MagicWithA_a;

Unfortunately it is quite cumbersome having to pass in the Class and Type template arguments every time to make the final pointer work.

Is there any way to have these arguments deduced by partial specialization, for example? That is, how can the Magic class be declared to make the below definitions work?

typedef Magic<&B::c> MagicWithB_c;
typedef Magic<&A::b> MagicWithA_b;

回答1:


With C++17 you can use auto non-type template parameter:

template<auto p_member>
struct Magic
{ };

Before C++17 only the longer variant that you've implemented would work.




回答2:


You can shorten it somewhat with specializations, yes. And if you don't mind resorting to macros you can have almost the syntax you want with c++11. First, a primary template specialization:

template<typename T, T pm>
struct MagicImpl; // Undefined for most types

Then a partial specialization for pointers to members, where we can freely add the parameters we wish to be deduced:

template<class Class, typename Type>
struct MagicImpl<Type Class::*, Type (Class::*Member)> {
};

And finally, we need to employ decltype to get the pointer to member type out of the pointer-to-member expression, which we hide behind the aforementioned macro:

#define MAGIC(...) MagicImpl<decltype(__VA_ARGS__), __VA_ARGS__>

And you can use it as follows:

typedef MAGIC(&B::c) MagicWithB_c;
typedef MAGIC(&A::b) MagicWithA_b;


来源:https://stackoverflow.com/questions/48478886/deducing-pointer-to-member-template-arguments

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!