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
}
};