I have the following functions defined:
template <typename T> buffer_t &operator<<(buffer_t &buffer, T data);
template <> buffer_t &operator<<(buffer_t &buffer, const char *data);
template <> buffer_t &operator<<(buffer_t &buffer, const Glib::ustring &data);
When I call:
buffer << Glib::ustring("hello");
The compiler uses the general template definition instead of the specialization with Glib::ustring.
What am I doing wrong here?
You have a function template, and you want to perform template argument deduction. For this purpose, your function call is matched against the templated function argument
T data. I believe that 14.8.2.4 applies to the partial ordering for your specialization wherePis the template argument andAis the type of the actual argument; emphasis is mine):Thus, since the type of your argument is
A = Glib::ustring, then this is not as good a match for the specializationconst Glib::ustring &as the primary template is, and even if you have an actual const-reference, the reference is stripped off during the partial ordering, and you again end up with a worse match.The usual way to fix this is to make your primary template a const-reference; this can also bind to temporary objects and should thus be “as good as” a value argument: