Compiler cannot deduce the specialised template in C++
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 instant开发者_运维问答iated." << 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.
First, what John Dibling said in a comment: please try to boil this down a bit. What would be ideal is to see something that does work alongside something similar that doesn't.
Just a guess, but by comparing with what you are intending to do via your pseudocode, it looks like you have messed up a couple of boost::mpl::or_
calls. Maybe
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>
>
>,
should be
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>
>,
At present you have what looks like 1 1-operand or_
and 1 3-operand or_
. According to the Boost MPL docs, or_
requires at least 2 operands, so perhaps your 1-operand or_
, which I take to invoke Undefined Behaviour, is wrecking things. (I'm surprised it compiles.)
You first define struct ConstrType{};
and then you reuse ConstrType as a template parameter here template<typename InType, typename OutType, typename ConstrType>
class getInterestRateIndex_impl{
?? ... That's asking for trouble. I'd rename one of them.
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
精彩评论