Template Specialization Not Used

I have the following functions:

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 a generic template definition instead of specializing with Glib :: ustring.

What am I doing wrong here?

+1
source share
2 answers

You have a function template and you want to output the template argument. For this purpose, your function call is mapped to the templated function T data argument. I believe that 14.8.2.4 relates to partial ordering for your specialization, where P is the template argument and A is the type of the actual argument; my accent):

Before performing partial ordering, some conversions are performed for the types used for partial ordering:

- If P is a reference type, P is replaced by the type indicated.

- If A is a reference type, A is replaced by the type indicated.

Thus, since the type of your argument is A = Glib::ustring , this is not so good for specializing const Glib::ustring & as the main template, and even if you have the actual const-reference, the link removed during the partial order, and you find yourself in a worse match again.

The usual way to fix this is to make your main template a constant reference; it can also bind to temporary objects and therefore should be "as good" as an argument to the value:

 template <typename T> buffer_t & operator<<(buffer_t & buffer, T const & data); // ^^^^^^^^^ 
+4
source
 template <typename T> buffer_t &operator<<(buffer_t &buffer, T data); 

is the main template. Specializations are not primary templates. The compiler finds only primary templates when the matching functions, and then, if the selected template function has specializations, they look at them, if the compiler search specialization exactly matches the parameters - it uses them, and the other uses the primary template.

 template <> buffer_t &operator<<(buffer_t &buffer, const Glib::ustring &data) 

this specialization does not exactly match buffer_t << Glib::ustring("s") , but it exactly matches

 template <> buffer_t &operator<<(buffer_t &buffer, Glib::ustring data) 

I suggest you not use a specialized template function, use overloading.

 template <typename T> buffer_t &operator<<(buffer_t &buffer, T data); buffer_t &operator<<(buffer_t &buffer, const char *data); buffer_t &operator<<(buffer_t &buffer, const Glib::ustring &data); 
+4
source

Source: https://habr.com/ru/post/986609/


All Articles