1

我定义了以下功能:

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 的特化。

我在这里做错了什么?

4

2 回答 2

5

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

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

— 如果P是引用类型,P则替换为引用的类型。

如果A是引用类型,A则替换为引用的类型。

因此,由于您的参数的类型是A = Glib::ustring,那么这对于专业化的匹配const Glib::ustring &不如主模板那么好,即使您有实际的 const 引用,在部分排序期间引用也会被剥离,并且您再次以更糟糕的比赛结束。

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

template <typename T> buffer_t & operator<<(buffer_t & buffer, T const & data);
//                                                             ^^^^^^^^^
于 2012-07-28T18:22:41.997 回答
5
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);
于 2012-07-28T19:13:46.287 回答