3

私はまだメタプログラミングのスイングを取得しようとしていますが、困惑しています。

私がやりたいのは、クラス/構造体/何でも作成し、std::tuple を提供し、タプルのオブジェクト型に基づいてメンバー関数を自動的に生成することです。目標は、クラスを派生させることですMessageHandler

例えば

typedef std::tuple< MessageA, MessageB, MessageC > MessageSet;

template< class T >
class MessageHandler
{
  // some magic metaprogramming would "create"...
  virtual void processMsg( const MessageA& ) = 0;
  virtual void processMsg( const MessageB& ) = 0;
  virtual void processMsg( const MessageC& ) = 0;
};

テンプレートに仮想関数を含めることはできないと読みましたが、それが C++11 でも当てはまるかどうかはわかりませんでした。

ありがとう。

4

2 に答える 2

5

答えは、次のような可変個引数テンプレート、部分的な特殊化、および継承です。

//primary template!
template<typename T>
class MessageHandler;

//variadic template, partial specialization and inheritance!
template<typename H, typename ...T>
class MessageHandler<std::tuple<H,T...>>  : public MessageHandler<std::tuple<T...>>
{
    virtual void processMsg( const H& ) = 0;
};

template<typename T>
class MessageHandler<std::tuple<T>>
{
    virtual void processMsg( const T& ) = 0;
};
于 2012-07-29T14:22:23.537 に答える
4

それを行うためにタプルは必要ありません:

struct MessageA{};struct MessageB{};struct MessageC{};

template <typename T>
struct message_interface {
  virtual void processMessage(const T& t) = 0;
};

template< typename... Args >
struct message_handler : public message_interface<Args>...
{};

struct message_impl : message_handler<MessageA, MessageB, MessageC>
{
  void processMessage(const MessageA&){}
  void processMessage(const MessageB&){}
  void processMessage(const MessageC&){}
};

int main()
{
  message_impl i;
  return 0;
}

引数リストが一意であり、静的にアサートされているかどうかを確認することをお勧めします。また、参照型やその他の望ましくないものが含まれていないことを確認してください。これらは通常、引数の型を作成しようとするとエラーになりますが、ユーザーに問題が発生することはありません。

編集:どうしてもサポートが必要な場合はtuple、専門化を追加してください:

template< typename... Args >
struct message_handler< std::tuple<Args...> > : public message_interface<Args>...
{};
于 2012-07-29T14:24:20.467 に答える