未使用模板专业化

n00*_*n00 1 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);
Run Code Online (Sandbox Code Playgroud)

我打电话的时候:

buffer << Glib::ustring("hello");
Run Code Online (Sandbox Code Playgroud)

编译器使用通用模板定义而不是Glib :: ustring的特化.

我在这做错了什么?

Ker*_* SB 5

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

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

- 如果P是引用类型,P则替换为引用的类型.

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

因此,由于你的参数的类型是A = Glib::ustring,那么这不像const Glib::ustring &主模板那样匹配专业化,即使你有一个实际的const-reference,在部分排序期间也会剥离引用,而你再次以更糟糕的比赛结束.

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

template <typename T> buffer_t & operator<<(buffer_t & buffer, T const & data);
//                                                             ^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)


For*_*veR 5

template <typename T> buffer_t &operator<<(buffer_t &buffer, T data);
Run Code Online (Sandbox Code Playgroud)

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

template <> buffer_t &operator<<(buffer_t &buffer, const Glib::ustring &data)
Run Code Online (Sandbox Code Playgroud)

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

template <> buffer_t &operator<<(buffer_t &buffer, Glib::ustring data)
Run Code Online (Sandbox Code Playgroud)

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

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);
Run Code Online (Sandbox Code Playgroud)