未使用模板专业化

时间:2012-07-28 18:20:25

标签: c++ templates

我定义了以下功能:

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);

我打电话的时候:

buffer << Glib::ustring("hello");

编译器使用通用模板定义而不是Glib :: ustring的专门化。

我在这里做错了什么?

2 个答案:

答案 0 :(得分:5)

您有功能模板,并且您想执行模板参数扣除。为此,您的函数调用将与模板化函数参数T data进行匹配。我相信14.8.2.4适用于你的专业化的部分排序,其中P是模板参数,A是实际参数的类型;重点是我的):

  

在完成部分排序之前,会对用于部分的类型执行某些转换   排序:

     

- 如果P是引用类型,P将被引用的类型替换。

     

- 如果A是参考类型,则A将替换为所引用的类型。

因此,由于你的参数类型是A = Glib::ustring,那么这不像主模板那样匹配专业化const Glib::ustring &,即使你有一个实际的const-reference ,在部分排序期间,参考被剥离,你最终会得到更糟糕的匹配。

解决此问题的常用方法是使主模板成为const-reference;这也可以绑定到临时对象,因此应该与值参数“一样好”:

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

答案 1 :(得分:4)

template <typename T> buffer_t &operator<<(buffer_t &buffer, T data);

是主要模板。专业化不是主要模板。编译器在匹配函数时只查找主模板,然后,如果选择模板函数有专门化,则查看这些,如果编译器找到特殊化,则完全匹配参数 - 使用它,否则使用主模板。

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

此专精化与操作buffer_t << Glib::ustring("s")不完全匹配,但这与

完全匹配
template <> buffer_t &operator<<(buffer_t &buffer, Glib::ustring data)

我建议你不要使用函数模板专门化,使用重载。

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);