I have overloaded a function in my string class, however, it never gets called. Why?
template <class T>
class StringT {
public:
void assign(const T* ptr);
template <size_t N> void assign(const T(&ptr)[N]);
};
int main() {
StringT<char> str;
str.assign("Hello World"); //calls "void assign(const T* ptr)" although type is (const char[12])
}
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.
Function templates. Function templates are special functions that can operate with generic types. This allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type. In C++ this can be achieved using template parameters.
You cannot have a virtual template function because as far as the compiler is concerned they are two completedly different functions; as their implicit this parameter is of different type.
Definition. As per the standard definition, a template class in C++ is a class that allows the programmer to operate with generic data types. This allows the class to be used on many different data types as per the requirements without the need of being re-written for each type.
For more reference, some specific references to the Standard are:
13.3.3 Best viable function
Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then...
- F1 is not a function template specialization and F2 is a function template specialization...
In this case, the non-templated function is (obviously) not a function template specialization and the conversion of "Hello World"
to char const*
is not worse than to const char[N]
, per the ranking rules defined in the Table in the "Standard conversion sequences" section. According to that Table, both No conversions required
and Array-to-pointer conversion
are considered an exact match in the context of overload resolution. Likewise, if the templated overloads are changed to a non-template overload (i.e., as void assign(const T(&ptr)[12]);
), then compilation of str.assign("Hello World");
will fail due to an ambiguous call.
To make sure the non-template function isn't considered for overload, there is the following note under the "Explicit template argument specification" section:
Note: An empty template argument list can be used to indicate that a given use refers to a specialization of a function template even when a non-template function (8.3.5) is visible that would otherwise be used.
So, you can use str.assign<>("Hello World");
for that.
When there is a choice compiler chooses most specialized function. When there is a non-template function than it is treated as more specialized than any template function
Details here
If you want to keep non-template function but forcibly call template one try
str.template assign("Hello World");
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