25

次のように、クラスメンバーへのポインタをテンプレートパラメータとして使用したいと思います。

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

このような構造体を使用すると問題なく動作しますが、とMyStruct<SomeClass, SomeResult, &SomeClass::value> variableを指定する必要があるのは好きではありません。SomeClassSomeResult

MyStruct<&SomeClass::value> variable可能であれば使用したいのですが、クラスをパスして結果タイプを取得する機能を失うことはありません。

次のことを試しましたが、構文が不正です。

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

エラー:テンプレートパラメータリストが多すぎます

ヘルパー関数を使用してみました(実際にはClangで機能しますが、GCCによって拒否されます)。

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

エラー:関数本体の外部でのパラメーター `member'の使用
エラー:テンプレート引数3が無効です

シンプルMyStruct<&SomeClass::value>にすることは可能ですか?もしそうなら、どのように?

私の質問を解決しなかった関連する質問:

4

4 に答える 4

14

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();
于 2017-01-04T23:43:54.157 に答える
11

私の質問に対する答えは、次のC++標準のためにこのペーパーで提案されました。

この構文が提案されました:

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

some_struct<&A::f> x;

新しい構文構造の必要性は、今ではそれができないことを示しています。

n3601が受け入れられることを願っています。:-)

于 2013-03-19T20:05:11.307 に答える
7

これは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;
};

これで、すべての構造体に対して追加の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>

...そしてそれを次のように使用します:

MyStruct(&SomeClass::value)  myStruct; // <-- object of type MyStruct<&SomeClass:value>

C ++ 17に切り替えるまで、これを中間ソリューションとして使用します。

于 2017-07-19T07:47:04.547 に答える
-6

結果クラスをテンプレートクラスの子にします。ポインタメンバーがパブリックなどの結果クラスのオブジェクトであると仮定すると、次のようにすることで任意のオブジェクトにアクセスできます。

template <stuff for this class> :: public result
{
    blah
}
于 2013-03-03T05:24:52.357 に答える