const char* 的模板方法专用化

Template method specialization for const char*

提问人:François Beaune 提问时间:7/30/2017 最后编辑:AustinWBryanFrançois Beaune 更新时间:2/6/2023 访问量:1062

问:

请考虑以下代码片段:

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

此错误的原因是什么,有没有办法编写专业化以使其有效?

我不是在寻找替代解决方案,我只是试图理解错误背后的逻辑。

C++ Templates Template-specialization 专业化

评论


答:

6赞 songyuanyao 7/30/2017 #1

您指定了错误的参数类型。

请注意,对于 ,它本身是限定的。那么 对于 = ,应该是(即对指针的引用),而不是(即对指针的引用)。const T&constTTchar*const T&char* const &constconst char* &const

顺便说一句,Clang 给出了更明确的错误消息:

候选模板被忽略:无法将“void (char *const &)”与“void (const char *&)”匹配


顺便说一句,因为 is a 确实不会调用规范,那么 的类型将被推导出为 ,这与 不匹配。如果你想让规范与 一起使用,那么它应该是s.insert("");""const char[1]Tchar [1]char *char[1]

template <>
void S::insert<char[1]>(char const (&) [1]) {}

然后

S s;
s.insert("");

但它只适用于 ,即只有一个元素的数组。我认为让它一起工作会更有意义,那么它应该是char[1]charconst char*

template <>
void S::insert<const char*>(const char * const &) {}

然后

S s;
const char* str = "";
s.insert(str);

评论

0赞 François Beaune 7/30/2017
我实际上已经尝试过了,但 gcc 仍然无法编译/链接它:undefined reference to 'void S::insert<char [1]>(char const (&) [1])'
0赞 songyuanyao 7/30/2017
@FrançoisBeaune 答案已修订。
0赞 dfrib 7/30/2017
是否有可能宣布一个腐朽的专业化,转发到一个,例如,为(字面上的)案例踢球?const char*s.insert("")
0赞 songyuanyao 7/30/2017
@dfri 否,主模板被声明为引用,然后将始终推导出为数组;如果它被声明为 ,那么将适用于 。Ttemplate <typename T> void insert(T x);template <> void S::insert<const char*>(const char*)insert("")
0赞 dfrib 7/30/2017
是的,当然,谢谢。出于好奇(并且没有删除主模板中的引用):这甚至包括尝试部分专业化模板“hacks”和显式使用 (/)?(我自己自然也尝试过,但没有成功)。std::decaystd::enable_if