I have the following code in a class
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>()( );
}
When I instantiate the class and invoke getInterestRateIndex<DerivedFromLiborType, BaseType>()
, the compiler cannot choose the specialisation. When I uncomment the exception
line, it can though detect that the Type
after typedef
is ConstrType2
. Am I missing anything that can hint the compiler to choose the right specialisation?
PS: the template logic suppose to do something like .....
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
)
)
I do this because I need to dispatch shared_ptr
based on the input type, and the desired underlying type in the shared_ptr wrapper.
The problem is that the outer if statement cannot deduce the type of the "then" branch and return a compounded type of boost structs and therefore always choosing the full unspecialised template