2

重複の可能性:
template<auto X> をエミュレートすることは可能ですか?

次の作業コードを検討してください。

#include <iostream>

template<typename T> struct Traits {};

template<typename T, typename A>
struct Traits<void(T::*)(A)>
{
   typedef T Class;
   typedef A Arg;
};

template<typename T, typename U, void(T::*MemFun)(U)>
void Builder()
{
   std::cout <<  typeid(T).name() << std::endl;
   std::cout <<  typeid(U).name() << std::endl;
   std::cout <<  typeid(MemFun).name() << std::endl;
}

template<typename T, T arg>
void Builder()
{
   return Builder<Traits<T>::Class,Traits<T>::Arg,arg>();
}

class Class
{
public:
   void foo(int) { }
};

int main()
{
   Builder<decltype(&Class::foo), &Class::foo>();
}

私ができるようにしたいのは、マクロを使用せずに同じ結果を得るために、このようなものです。

int main()
{
   Builder<&Class::foo>();
}

メンバーへのポインタを取り、型を推測するテンプレートを作成できないようです。何かご意見は?メンバーへのポインターは、テンプレート関数 (表示されていません) の作成に使用されるため、関数パラメーターではなく、テンプレート引数として使用する必要があります。

4

3 に答える 3

4

できません。型以外のテンプレート引数を指定するには、型を指定する必要があります。したがって、Builder を特定の 1 つのタイプのみに制限するか、2 番目の引数のタイプである追加の引数 (リストの最初) が必要です。メンバ ポインタを constexpr として使用したくない場合は、簡単です。

template <typename T, typename M>
struct Builder {
   M T::*ptr;
   Builder( M T::*ptr ) : ptr(ptr) {}
};
template <typename T, typename M>
Builder<T,M> createBuilder( M T::*ptr ) {
   return Builder<T,M>(ptr);
}
int main() {
   auto bld = createBuilder( &Class::member );
}
于 2012-08-20T19:39:29.583 に答える
3

私は自分で同様のことをしようと時間を費やしてきました。

Class::foo関数の名前を2回使わないと無理だと思います。私の推論は次のとおりです。

  • の型を取得するには、テンプレート関数の引数としてfoo使用decltypeまたは指定する必要がありますfoo
  • foo上記のいずれかで、 (テンプレート引数として使用できるようにする)のconstexpr-nessが失われます
  • fooさらに、上記と同じ問題に直面するため、テンプレート クラスまたは関数内で「複製」することはできません。
  • 結論:foo外側のスコープで 2 回入力する必要があります

C++11 であっても、「汚い」マクロ トリックなしでは逃げられないようです...

于 2012-08-20T19:09:45.133 に答える
0

残念ながら、非型テンプレート パラメータの型について型推定を行う方法はありません。ここでは、マクロが実際に唯一のオプションです。

于 2012-08-20T18:56:05.250 に答える