Компилятор не может вывести специализированный шаблон в C ++ - PullRequest
0 голосов
/ 18 ноября 2010

У меня есть следующий код в классе

  struct ConstrType{};
  struct ConstrType3{};
  struct ConstrType2{};
  struct ConstrType1{};

  template<typename InType, typename OutType, typename ConstrType>
  class getInterestRateIndex_impl{
  public:
    getInterestRateIndex_impl(){
      std::cout << "Generic getInterestedRateIndex_impl instantiated. Failed" << std::endl;
//      BOOST_STATIC_ASSERT(sizeof(ConstrType) == 0);
    }
    boost::shared_ptr<OutType> operator()() const{
      return boost::shared_ptr<OutType>();
    }
  };


  template<typename InType, typename OutType>
  class getInterestRateIndex_impl<InType, OutType, ConstrType2>{
  public:
    getInterestRateIndex_impl(){
      std::cout << "ConstrType2 getInterestedRateIndex_impl instantiated." << std::endl;
    }
    boost::shared_ptr<OutType> operator()() const{
      return boost::shared_ptr<OutType>();
    }
  };


  template<typename InType, typename OutType>
  class getInterestRateIndex_impl<InType, OutType, ConstrType1>{
  public:
    getInterestRateIndex_impl(){
      std::cout << "ConstrType1 getInterestedRateIndex_impl instantiated." << std::endl;
    }
    boost::shared_ptr<OutType> operator()() const{
      return boost::shared_ptr<OutType>();
    }
  };



  template<typename InType, typename OutType>
  boost::shared_ptr<OutType> getInterestRateIndex() const{
//    BOOST_STATIC_ASSERT(boost::is_base_of<OutType, InType>::value);

    typedef typename
      boost::mpl::if_
      <
          boost::is_same<InType, QuantLib::Libor>,
          QuantLib::Libor,
          boost::mpl::if_
          <
              boost::mpl::or_
              <
                  boost::mpl::or_
                  <
                      boost::is_same<InType, QuantLib::Euribor>,
                      boost::is_same<InType, QuantLib::EURLibor>,
                      boost::is_base_of<QuantLib::Libor, InType>
                  >
              >,
              ConstrType2,
              boost::mpl::if_
              <
                  boost::mpl::or_
                  <
                      boost::is_base_of<QuantLib::Euribor, InType>,
                      boost::is_base_of<QuantLib::EURLibor, InType>
                  >,
                  ConstrType1,
                  ConstrType
              > 
          > 
      >::type Type;
//    std::cout << typeid(Type).name() << std::endl;
//    throw std::exception(typeid(Type).name());

    return getInterestRateIndex_impl<InType, OutType, Type>()( );

  }

Когда я создаю экземпляр класса и вызываю getInterestRateIndex<DerivedFromLiborType, BaseType>(), компилятор не может выбрать специализацию. Когда я раскомментирую строку exception, он может обнаружить, что Type после typedef равно ConstrType2. Я скучаю по чему-нибудь, что может подсказать компилятору, чтобы выбрать правильную специализацию?

PS: шаблон логики предполагает что-то вроде .....

if(T is Libor)
    return LiborType
if(
   or(
      or(T = Euribor,
         T = EURLibor),
      is_base_of(T, Libor)
    ),
    ConstrType2,
    if( 
        or(is_base_of(T, Euribor),
           is_base_of(T, EURLibor)),
       ConstrType1,
       ConstrType
      )
   )

Я делаю это, потому что мне нужно отправить shared_ptr на основе типа ввода и требуемого базового типа в оболочке shared_ptr.

Ответы [ 3 ]

1 голос
/ 18 ноября 2010

Во-первых, что сказал Джон Диблинг в комментарии: пожалуйста, попробуйте немного свести это.Что было бы идеально, так это увидеть то, что работает вместе с чем-то похожим, что не .

Просто предположение, но сравнивая с тем, что вы собираетесьчерез ваш псевдокод, похоже, что вы перепутали пару boost::mpl::or_ звонков.Возможно

          boost::mpl::or_
          <
              boost::mpl::or_
              <
                  boost::is_same<InType, QuantLib::Euribor>,
                  boost::is_same<InType, QuantLib::EURLibor>,
                  boost::is_base_of<QuantLib::Libor, InType>
              >
          >,

должно быть

          boost::mpl::or_
          <
              boost::mpl::or_
              <
                  boost::is_same<InType, QuantLib::Euribor>,
                  boost::is_same<InType, QuantLib::EURLibor>
              >,
              boost::is_base_of<QuantLib::Libor, InType>
          >,

В настоящее время у вас есть то, что выглядит как 1 1-операнд or_ и 1 3-операнд or_.Согласно документам Boost MPL , для or_ требуется как минимум 2 операнда, так что, возможно, ваш 1-операнд or_, который я использую для вызова Undefined Behavior, разрушает вещи.(Я удивлен, что он компилируется.)

0 голосов
/ 19 ноября 2010

Проблема в том, что внешний оператор if не может определить тип ветви then и вернуть сложный тип структур наддува и поэтому всегда выбирает полный неспециализированный шаблон

0 голосов
/ 18 ноября 2010

Сначала вы определяете struct ConstrType{}; , а затем повторно используете ConstrType в качестве параметра шаблона здесь template<typename InType, typename OutType, typename ConstrType> class getInterestRateIndex_impl{ ??... Это напрашивается на неприятности.Я бы переименовал одного из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...