编译器无法推断出C ++中的专用模板

时间:2010-11-17 21:04:43

标签: c++ templates compiler-construction

我在类

中有以下代码
  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之后的typedefConstrType2。我错过了任何可以暗示编译器选择正确的专业化的东西吗?

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 个答案:

答案 0 :(得分:1)

首先,John Dibling在评论中说:请尝试将其降低一点。什么是理想的是看到的东西与的类似东西一起工作。

只是一个猜测,但通过比较您打算通过伪代码进行的操作,看起来你已经搞砸了几个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个操作数or_和1个3个操作数or_。根据{{​​3}},or_需要至少2个操作数,所以我用来调用未定义行为的1操作数or_可能会破坏事物。 (我很惊讶它编译。)

答案 1 :(得分:0)

首先定义struct ConstrType{}; ,然后在这里重用ConstrType作为模板参数template<typename InType, typename OutType, typename ConstrType> class getInterestRateIndex_impl{ ?? ......那是在惹麻烦。我会重命名其中一个。

答案 2 :(得分:0)

问题是外部if语句不能推断出“then”分支的类型并返回一个复合类型的boost结构,因此总是选择完整的非专用模板