Reputation: 2657
based on this question and the answer provided by "Dave", how to specialize the case for handling the non-integral types to handle a type say QDate
(used in Qt for handling date related tasks)?
The function I want to specialize is:
void extract(const std::string str)
{
std::bitset<sizeof(T) * CHAR_BIT> bs(str.substr(m_start, m_len));
m_data = static_cast<T>(bs.to_ulong());
}
an std::string
of 1s and 0s is supplied to this function and then based on an start and length I need to convert it to the type the template class containing this function was instantiated with. It doesn't make sense when the type is not integral or can't be produced using the std::bitset
.
Upvotes: 0
Views: 462
Reputation: 109159
I'm not sure I understand your use case completely, but I think it's something similar to this
template<typename T>
struct foo
{
T m_data;
// others ...
void extract(const std::string str)
{
std::bitset<sizeof(T) * CHAR_BIT> bs(str.substr(m_start, m_len));
m_data = static_cast<T>(bs.to_ulong());
}
};
But you want extract
to do something different when foo
is instantiated with QDate
. There are a few different ways to get this done, SFINAE being one of them.
But you can't simply tack on an enable_if
expression to extract
because for SFINAE to work the substitution failure needs to happen in the immediate context, and T
is known by the time foo<T>::extract
is instantiated. So add a dummy template parameter to extract
that defaults to T
.
template<typename U=T>
typename std::enable_if<std::is_same<U, QDate>::value>::type
extract(const std::string str)
{
// this will be used when T=QDate
}
template<typename U=T>
typename std::enable_if<!std::is_same<U, QDate>::value>::type
extract(const std::string str)
{
// this will be used when T!=QDate
}
If extract
is the only thing that changes behavior then another way to accomplish this would be to move all common functionality to another class which foo
would inherit from.
template<typename T>
struct foo_base
{
// common functionality
};
template<typename T>
struct foo : foo_base<T>
{
void extract(const std::string str)
{
std::bitset<sizeof(T) * CHAR_BIT> bs(str.substr(m_start, m_len));
m_data = static_cast<T>(bs.to_ulong());
}
};
// Specialization for QDate
template<>
struct foo<QDate> : foo_base<QDate>
{
void extract(const std::string str)
{
// QDate specific functionality
}
};
Upvotes: 1