const char* 的模板方法特化
Template method specialization for const char*
考虑这个片段:
struct S {
template <typename T>
void insert(const T& x);
};
template <>
void S::insert<char*>(const char*& x) {}
int main() {
S s;
s.insert("");
return 0;
}
gcc 编译失败,出现以下错误信息:
error: template-id 'insert<char*>' for 'void S::insert(const char*&)' does not match any template declaration
此错误的原因是什么,有没有一种方法可以编写专用化以使其起作用?
我不是在寻找替代解决方案,我只是想了解错误背后的逻辑。
您指定了错误的参数类型。
请注意,对于 const T&
,const
在 T
本身上是合格的。那么对于 T
= char*
,const T&
应该是 char* const &
(即引用 const
指针),而不是 const char* &
(即引用指向const
).
顺便说一句 Clang 给出了更清晰的错误信息:
candidate template ignored: could not match 'void (char *const &)' against 'void (const char *&)'
顺便说一句,对于 s.insert("");
规范将不会被调用,因为 ""
确实是一个 const char[1]
,那么 T
的类型将被推断为 char [1]
,与 char *
不匹配。如果您希望规范适用于 char[1]
,那么它应该是
template <>
void S::insert<char[1]>(char const (&) [1]) {}
然后
S s;
s.insert("");
但它只适用于 char[1]
,即只有一个元素的 char
数组。我认为让它与 const char*
一起工作会更有意义,那么它应该是
template <>
void S::insert<const char*>(const char * const &) {}
然后
S s;
const char* str = "";
s.insert(str);
考虑这个片段:
struct S {
template <typename T>
void insert(const T& x);
};
template <>
void S::insert<char*>(const char*& x) {}
int main() {
S s;
s.insert("");
return 0;
}
gcc 编译失败,出现以下错误信息:
error: template-id 'insert<char*>' for 'void S::insert(const char*&)' does not match any template declaration
此错误的原因是什么,有没有一种方法可以编写专用化以使其起作用?
我不是在寻找替代解决方案,我只是想了解错误背后的逻辑。
您指定了错误的参数类型。
请注意,对于 const T&
,const
在 T
本身上是合格的。那么对于 T
= char*
,const T&
应该是 char* const &
(即引用 const
指针),而不是 const char* &
(即引用指向const
).
顺便说一句 Clang 给出了更清晰的错误信息:
candidate template ignored: could not match 'void (char *const &)' against 'void (const char *&)'
顺便说一句,对于 s.insert("");
规范将不会被调用,因为 ""
确实是一个 const char[1]
,那么 T
的类型将被推断为 char [1]
,与 char *
不匹配。如果您希望规范适用于 char[1]
,那么它应该是
template <>
void S::insert<char[1]>(char const (&) [1]) {}
然后
S s;
s.insert("");
但它只适用于 char[1]
,即只有一个元素的 char
数组。我认为让它与 const char*
一起工作会更有意义,那么它应该是
template <>
void S::insert<const char*>(const char * const &) {}
然后
S s;
const char* str = "";
s.insert(str);