指向类成员的指针作为模板参数

kay*_*kay 21 c++ templates pointer-to-member c++11 c++14

我想使用指向类成员的指针作为模板参数,如下所示:

template <class Class, class Result, Result Class::*Member>
struct MyStruct {
    // ...
};
Run Code Online (Sandbox Code Playgroud)

使用这个结构MyStruct<SomeClass, SomeResult, &SomeClass::value> variable就好了,但我不喜欢我必须指定SomeClassSomeResult.

我想使用,MyStruct<&SomeClass::value> variable如果这是可能的,但不会失去传递任何类和任何结果类型的能力.

我尝试了以下方法,但语法是非法的:

template <class Class, class Result>
template <Result Class::*Member>
struct MyStruct {
    // ...
};
Run Code Online (Sandbox Code Playgroud)

错误:模板参数列表太多

我尝试使用辅助函数(实际上在Clang中工作但被GCC拒绝):

template <class Class, class Result>
static constexpr auto makeMyStruct(Result Class::*member) ->
MyStruct<Class, Result, member> {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

错误:在函数体外使用参数`member'
错误:模板参数3无效

有可能有一个简单的MyStruct<&SomeClass::value>,如果是这样,怎么样?

相关问题没有解决我的问题:

kay*_*kay 11

本文针对下一个即将推出的C++标准提出了我的问题的答案:

提出了这种语法:

template<using typename T, T t>
struct some_struct { /* ... */ };

some_struct<&A::f> x;
Run Code Online (Sandbox Code Playgroud)

对新语法结构的需求表明你现在不能这样做.

我希望n3601会被接受.:-)


Eri*_*ric 10

在c ++ 17中,添加了auto模板参数(P0127),我认为你现在可以做到:

template<auto value>
struct MyStruct {};

template<typename Class, typename Result, Result Class::* value>
struct MyStruct<value> {
    // add members using Class, Result, and value here
    using containing_type = Class;
};

typename MyStruct<&Something::theotherthing>::containing_type x = Something();
Run Code Online (Sandbox Code Playgroud)


Man*_*ork 6

这可能是C++ 11中的一个解决方案:

您可以定义以下泛型类型特征:

template<class T>
struct remove_member_pointer {
  typedef T type;
};

template<class Parent, class T> 
struct remove_member_pointer<T Parent::*> {
  typedef T type;
};

template<class T>
struct baseof_member_pointer {
  typedef T type;
};

template<class Parent, class T>
struct baseof_member_pointer<T Parent::*> {
  typedef Parent type;
};
Run Code Online (Sandbox Code Playgroud)

现在,您可以为每个结构定义一个额外的4行包装器宏:

template<class Class, class Result, Result Class::*Member>
struct _MyStruct {
  // ...
};

#define MyStruct(MemberPtr) \
  _MyStruct<baseof_member_pointer<decltype(MemberPtr)>::type, \
            remove_member_pointer<decltype(MemberPtr)>::type, \
            MemberPtr>
Run Code Online (Sandbox Code Playgroud)

...并按以下方式使用它:

MyStruct(&SomeClass::value)  myStruct; // <-- object of type MyStruct<&SomeClass:value>
Run Code Online (Sandbox Code Playgroud)

我使用它作为中间解决方案,直到我们切换到C++ 17.