3

テンプレート内のメンバーへのポインター型を使用していますが、現在、次のようなことが起こっています。

template <typename Base, typename Type, Type Base::* Var>
struct Member
{
    //Stuff goes here.
};

ただし、BaseとTypeはVarの型に含まれているため、Base、Type、Varの順に定義する必要があるのは少し冗長に思えます。

これを行う方法はありますか?たとえば、Member構造体を使用/呼び出すときに、単一のメンバーへのポインター引数のみを使用する必要がありますか?理論的には、次のようなものです。

template <typename Base, typename Type, Type Base::* Var>
struct Member<Var>
{
    //stuff goes here
};

struct S
{
    int memberVal;
};

int main()
{
    Member<&S::memberVal> example;
};

助けてくれてありがとう!

4

2 に答える 2

1

とんでもない。最初のバリアントのみが正しいです。あなたは、C++構文がそれほどエレガントではない例を示しています。そのままビット。

2番目の例には、テンプレートの特殊化の構文があります。それは新しいテンプレートの定義ですが。ほとんどの場合、これは異議申し立てとして扱われます。

于 2012-08-08T04:01:51.190 に答える
1

あなたが求めていることは、C++で直接達成することはできません。制限は、型以外のテンプレート引数の場合、型をテンプレート定義で指定する必要があることです。型の推定は、関数の引数にのみ適用されます。

実際のユースケースに応じて、実行できる代替手段がありますが、それらは、メンバーポインターをテンプレート引数(コンパイル時)から関数引数(ランタイム)に移動することを意味します。つまり、次のタイプが与えられます。

template <typename C, typename M>
struct Member {
   M C::*ptr;
   Member( M C::*ptr ) : ptr(ptr) {}
};

次の構文でそのインスタンスを作成することができます。

auto x = create_member( &S::memberVal );

いくつかのメタプログラミングのトリックを使用することで、それほど複雑ではありませんが、次のようになります。

template <typename T> struct MemberType;
template <typename T, typename M> 
struct MemberType<M T::*> {
   typedef Member<T,M> type;
};
template <typename T>
typename MemberType<T>::type
create_member( T mbrptr ) {
    typename MemberType::type r(mbrptr);
    return r;
}

しかし、すでに述べたように、これはコンパイル時の引数を実行時の引数に変換することを意味し、したがってコンパイラーが行う最適化の一部(つまりインライン化)を潜在的に阻害します。

于 2012-08-08T05:02:52.223 に答える