Is it possible to call a function defined in a non-specialised template class from a specialised template class? Here is an example of what i am attempting:
template <typename T>
struct Convert
{
static inline void toString(unsigned num, unsigned places, std::string& str) { ... }
};
template <>
struct Convert<int8_t>
{
static inline void toString(unsigned num, std::string& str)
{
Convert<int8_t>::toString(num, digitis(num), str);
}
};
GCC complains that it can't see the non-specialised class function; i.e. I guess it only looks within the specialised class.
Any thoughts?
EDIT
Here is a more concrete example from my code (with a possible solution):
struct NonSpecial { };
template <typename T>
class Convert
{
template <typename R>
static inline R fromString(const register char *str, const unsigned str_len)
{
R result = 0;
//convert str to R
return result;
}
friend class Convert<int8_t>;
friend class Convert<uint8_t>;
}
template <>
struct Convert<int8_t>
{
static inline int8_t fromString(const register char* str, const unsigned str_len = 4)
{
Convert<NonSpecial>::fromString<int8_t>(str, str_len);
}
};
template <>
struct Convert<uint8_t>
{
static inline uint8_t fromString(const register char* str, const unsigned str_len = 3)
{
Convert<NonSpecial>::fromString<uint8_t>(str, str_len);
}
};
I have other functions - toString(), countDigits(), etc. I have chosen this approach so I can keep the same function names for each type (i.e. don't need toStringU32(), toString32, etc.). I considered template specialization but I don't believe this is possible.
A non-template class can have template member functions, if required. Notice the syntax. Unlike a member function for a template class, a template member function is just like a free template function but scoped to its containing class.
The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.
An explicit specialization of a function template is inline only if it is declared with the inline specifier (or defined as deleted), it doesn't matter if the primary template is inline.
For normal code, you would use a class template when you want to create a class that is parameterised by a type, and a function template when you want to create a function that can operate on many different types.
In general, this isn’t possible.
There are different possible solutions but they “cheat”. The first is to hoist off the actual default logic into a different function that is not specialized. Now you can call this function from both toString
implementations.
The second alternative entails inheriting from the non-specialized class and passing a special tag as the template argument:
struct BaseClassTag { };
template <>
struct Convert<int8_t> : public Convert<BaseClassTag>
{
typedef Convert<BaseClassTag> TBase;
static inline void toString(unsigned num, std::string& str)
{
TBase::toString(num, digitis(num), str);
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With