7

これがC++03では不可能だったことは知っていますが、これを可能にする新しいブードゥーがあることを望んでいます。下記参照:

template <class T>
struct Binder
{
    template<typename FT, FT T::*PtrTomember>
    void AddMatch();
};
struct TestType
{
    int i;
};
int main(int argc, char** argv)
{
    Binder<TestType> b;
    b.AddMatch<int,&TestType::i>(); //I have to do this now
    b.AddMatch<&TestType::i>(); //I'd like to be able to do this (i.e. infer field type)
}

C ++ 11でこれを行う方法はありますか?decltypeは役に立ちますか?

**更新:Vladの例を使用して、私はこのようなものが機能すると考えていました(警告:現在decltypeをサポートするコンパイラを構築しているため、コンパイルしていません)

template <class T>
struct Binder
{
    template<typename MP, FT ft = decltype(MP)>
    void AddMatch()
    {
        //static_assert to make sure MP is a member pointer of T
    }
};
struct TestType
{
    int i;
};
int main()
{
    Binder<TestType> b;
    b.AddMatch<&TestType::i>();  
}

これは機能しますか?

4

4 に答える 4

3

実行しようとしていることは実行できません。つまり、型がない限り、メンバーポインタを定数式として使用することはできません。つまり、型以外のテンプレート引数の型を指定する必要があります。つまり、テンプレート引数の型推論はありません。

于 2012-05-17T20:09:11.440 に答える
2

これはどうですか(キッカーとしてc ++ 03で動作します):

#include <iostream>
#include <typeinfo>

template< typename T > struct ExtractMemberTypeHelper;
template< typename R, typename T >
struct ExtractMemberTypeHelper< R(T::*) >
{
    typedef R Type;
    typedef T ParentType;
};

template< typename T >
struct ExtractMemberType : public ExtractMemberTypeHelper< T > {};

struct foo
{
    int bar;
    template< typename T >
    void func( const T& a_Arg )
    {
        std::cout << typeid( typename ExtractMemberType< T >::Type ).name( ) << " " << typeid( typename ExtractMemberType< T >::ParentType ).name( ) << std::endl;
    }
};

int main()
{
    foo inst;
    inst.func( &foo::bar );
}
于 2012-05-17T20:20:45.190 に答える
2

「T」にこの情報を提供させることができます。

template <class ...T>
struct BoundTypes { };

template <class U, class T>
struct BinderDecls { 
  void AddMatch();
};

template <class U, class T, class ...Ts>
struct BinderDecls<U, BoundTypes<T, Ts...>>
  :BinderDecls<U, BoundTypes<Ts...>>
{ 
  using BinderDecls<U, BoundTypes<Ts...>>::AddMatch;

  template<T U::*PtrTomember>
  void AddMatch();
};

template <class T>
struct Binder : BinderDecls<T, typename T::bound_types> 
{ }

そうすれば簡単になります

struct TestType {
    typedef BoundTypes<int, float> bound_types;

    int i;
    float j;
};

int main(int argc, char** argv)
{
    Binder<TestType> b;
    b.AddMatch<&TestType::i>();
    b.AddMatch<&TestType::j>();
}

または、フレンド関数の定義を使用することもできます

template <class ...T>
struct BoundTypes { };

template <class U, class T>
struct BinderDecls {
  template<T U::*ptr>
  friend void addMatch(BinderDecl &u) {
   // ...
  }
};

template <class U, class ...Ts>
struct BinderDecls<U, BoundTypes<Ts...>> : BinderDecls<U, Ts>...
{ };

template<typename = void> 
void addMatch() = delete;

template <class T>
struct Binder : BinderDecls<T, typename T::bound_types> 
{ }

その後、あなたは書くことができます

struct TestType {
    typedef BoundTypes<int, float> bound_types;

    int i;
    float j;
};

int main(int argc, char** argv)
{
    Binder<TestType> b;
    addMatch<&TestType::i>(b);
    addMatch<&TestType::j>(b);
}
于 2012-05-17T21:22:47.303 に答える
0
template <class T>
struct Binder
{
    template<typename FT>
    void AddMatch();
};

struct TestType
{
    int i;
};

int main()
{
    Binder<TestType> b;
    b.AddMatch<decltype(&TestType::i)>();
}
于 2012-05-17T19:59:23.270 に答える