我定义了以下功能:
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的特化.
我在这做错了什么?
您有一个功能模板,并且您想要执行模板参数推断.为此,您的函数调用将与模板化函数参数进行匹配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)
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)
| 归档时间: |
|
| 查看次数: |
1082 次 |
| 最近记录: |