标准::tuple_element<>::类型解析问题

std::tuple_element<>::type resolution issues

本文关键字:类型 问题 gt lt tuple element 标准      更新时间:2023-10-16

正如您在下面的代码中看到的,我试图模拟一个回调结构,将消息的std::tuple<>提供给工厂。我的问题是,它看起来像编译器没有减少(例如)std::tuple_element< 2, MessageOne, MessageTwo, MessageTen >的"返回类型"只是MessageTwo -这是混淆的链接。见下文。

#include <map>
#include <tuple>
//----------------------------------------------------------------------
//
class MessageBase
{
  public:
    MessageBase( const int _id ) : m_id( _id ) { }
    virtual int getMessageID() const = 0;
  private:
    const int m_id;
};
#define MESSAGE( NAME, VAL ) 
  class Message##NAME : public MessageBase { 
    public: 
      Message##NAME() : MessageBase( VAL ) { } 
      virtual int getMessageID() const { return ( VAL ); } 
  }
  MESSAGE( One, 1 );
  MESSAGE( Two, 2 );
  MESSAGE( Ten, 10 );
class StaticMessageHandlerInterface
{
  public:
    virtual void processMsg( const MessageOne& ) { }
    virtual void processMsg( const MessageTwo& ) { }
    virtual void processMsg( const MessageTen& ) { }
};

//----------------------------------------------------------------------
//
class MessageCallbackInterface
{
  public:
    virtual void receiveMsg( const MessageBase* ) = 0;
};
template< class MessageT, class HandlerT >
class MessageCallbackHandler : public MessageCallbackInterface
{
  public:
    MessageCallbackHandler( HandlerT& _handler )
      : r_handler( _handler )
    { }
    void receiveMsg( const MessageBase* _msg )
    {
      const MessageT* msg( ( const MessageT* )(_msg) );
      r_handler.processMsg( *msg );
    }
  private:
    HandlerT& r_handler;
}; // MessageCallbackHandler

//----------------------------------------------------------------------
//
template< typename TupleT >
class MessageFactory
{
  public:
    MessageFactory()
      : p_handler( nullptr )
    {
      init( TupleT() );
    }
  private:
    StaticMessageHandlerInterface* p_handler;
    typedef std::map< int, MessageCallbackInterface* > MessageCallbackMap;
    MessageCallbackMap m_callbackMap;
    template< std::size_t I = 0, typename ... T >
    inline typename std::enable_if< I < sizeof ... (T), void >::type
    init( const std::tuple< T... >& t )
    {
      const auto& msg( std::get<I>( t ) );
      m_callbackMap[ msg.getMessageID() ] =
        new MessageCallbackHandler <
          std::tuple_element< I, std::tuple< T ... > >,
          StaticMessageHandlerInterface
         > ( *p_handler ) ;
      init< I + 1, T... >( t );
    }
    template< std::size_t I = 0, typename ... T >
    inline typename std::enable_if< I == sizeof... (T), void >::type
    init( const std::tuple< T... >& ) { }
};
//----------------------------------------------------------------------
//
int
main( const int, const char** )
{
  typedef std::tuple< MessageOne, MessageTwo, MessageTen > Foople;
  typedef MessageFactory< Foople > FoopleFactory;
  FoopleFactory factory;
}

test.C:在实例化'void MessageCallbackHandler(MessageT,HandlerT)::receiveMsg(const MessageBase*) [with MessageT = . .std::tuple_element(2u, std::tuple(MessageOne, MessageTwo, MessageTen));HandlerT = StaticMessageHandlerInterface]': test.C:143:5:
test.C:83:11:错误:没有匹配的函数调用"StaticMessageHandlerInterface:: processMsg (conststd::tuple_element(2u, std::tuple(MessageOne, MessageTwo, MessageTen)),)r_handler。processMsg(*msg);^ test.C:83:11:注:候选人是:test.C:57:22:注:virtual void StaticMessageHandlerInterface::processMsg(const . c:57:22)MessageOne&)虚拟void processMsg(const MessageOne&){}^ test.C:57:22:注意:const std::tuple_element(2u, std::tuple(MessageOne,MessageTwo, MessageTen))' to 'const MessageOne&' test.C:58:22:注意:StaticMessageHandlerInterface::processMsg(constMessageTwo&)processMsg(const MessageTwo&){}^ test.C:58:22:注意:const std::tuple_element(2u, std::tuple(MessageOne,MessageTwo, MessageTen))' to 'const MessageTwo&' test.C:59:22:注意:StaticMessageHandlerInterface::processMsg(constMessageTen&)虚拟void processMsg(const MessageTen&){}^ test.C:60:22:注意:const std::tuple_element(2u, std::tuple(MessageOne,MessageTwo, MessageTen))' to 'const MessageTen&'

(抱歉降价屠宰。编译它可能更容易)

您需要访问内部类型定义来获取实际的元素类型。现在你传入的是std::tuple_element类型。

  m_callbackMap[ msg.getMessageID() ] =
    new MessageCallbackHandler <
      typename std::tuple_element< I, std::tuple< T ... > >::type,
      StaticMessageHandlerInterface
     > ( *p_handler ) ;