I'm working with/learning template function specialization rules. I start with this function
template<typename T>
std::string toString(const T& t)
{
ostringstream out;
out << t;
return out.str();
}
Now I'd like to specialize it for const char*
typedef const char* ccharPtr;
template<>
std::string toString(const ccharPtr& s)
{
cout << "in specialization" << endl; // just to let me know
return std::string(s);
}
I'd like to do that without a typedef, but so far I can't figure it out.
That specialization works for a const char*, but not for a char*.
const char* s1 = "Hi"
cout << toString(s1); // works
char s2[] = "There";
cout << toString(s2); // doesn't work, since s2 isn't const char*
cout << toString(", Bob"); // doesn't work. Why not?
I'd like a single specialization to work for each case, but having trouble figuring it out.
Why specialise? Just overload the function. Fully specialising function templates is usually not required.
template <typename T>
std::string toString(const T& in)
{
ostringstream out;
out << in;
return out.str();
}
std::string toString(char const* in)
{
return in;
}
OK, if you really want to do this, then you have to consider that the type of string literals — although they implicitly convert to char const*
— is char const[N]
.
template <typename T>
std::string toString(T const & t) {
ostringstream out;
out << t;
return out.str();
}
template <>
std::string toString(char const* const & s) {
cout << "(S1)";
return std::string(s);
}
template <size_t N>
std::string toString(char (&s)[N]) {
cout << "(S2)";
return std::string(s);
}
template <size_t N>
std::string toString(char const (&s)[N]) {
cout << "(S3)";
return std::string(s);
}
int main() {
const char* s1 = "Hi";
cout << toString(s1) << endl;
char s2[] = "There";
cout << toString(s2) << endl;
cout << toString(", Bob") << endl;
}
// Output:
// (S1)Hi
// (S2)There
// (S3), Bob
Live demo.
You can omit specialisation S2
, and then both "There"
and ", Bob"
will use S3
.
Be warned that, actually, this isn't specialisation at all. I've rather cheated by creating new function templates. But I had to to get the size_t
parameter in; you could only do real specialisation here if you picked one value for N
and wrote it into the function signature as part of a concrete type, or if you could partially specialise function templates.
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