引用 const 的模板特化

Luc*_*uca 3 c++ templates template-specialization function-templates

我试图了解模板专业化是如何工作的。我有以下功能模板:

template <typename T>
void function(const T &t1, const T &t2)
{
    std::cout << "in function template: " << t1 << ", " << t2 << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

现在,我想专门化这个函数模板,以防它被一个指向 const 的指针调用:

// template specialization
template <>
void function(const char *&t1, const char *&t2)
{
    std::cout << "in compare template specialization: " << t1 << ", " << t2 << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

但是编译器抱怨它找不到专门化的函数模板:

In file included from main.cpp:1:0:
template.h:23:5: error: template-id 'compare<>' for 'int compare(const char*&, const char*&)' does not match any template declaration
 int compare(const char *&t1, const char *&t2)
     ^~~~~~~
template.h:10:5: note: candidate is: template<class T> int compare(const T&, const T&)
 int compare(const T &t1, const T &t2)
Run Code Online (Sandbox Code Playgroud)

如果我像这样专门化模板(对指向 const 的 CONST 指针的引用),它会起作用:

// template specialization
template <>
int compare(const char * const &t1, const char * const &t2)  // now the pointer itself is const
{
    std::cout << "in compare template specialization: " << t1 << ", " << t2 << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我想用 a 调用函数,const char *Ptr = "hello world"所以我认为推断的参数 T 是 char*,参数是 const char *&。

函数模板参数列表中的const不总是低级const吗?

Mic*_*zel 6

模板不是像宏一样简单的令牌替换机制。const T这里并不意味着“将任何T内容粘贴到”之后的位置const。这意味着那里的事物的类型是“const无论T是什么”。在你的函数模板的情况下,如果设置Tconst char*,那么该类型const T&将是一个参考const什么T是,即,在参考const char*其本身const,即const char * const &。这与 ifT是 typedef 名称而不是模板参数真的没有什么不同,例如:

using T = int*;
const T blub = 42;  // type of blub is int* const, not const int*
Run Code Online (Sandbox Code Playgroud)

所以,

template <>
void function(const char*& t1, const char*& t2);
Run Code Online (Sandbox Code Playgroud)

不是函数模板的有效特化function。没有T,你可以代入模板function得到这个签名。如果你替换const char*parameter T,即 form function<const char*>,它的签名会出来

void function<const char*>(const char * const& t1, const char * const& t2);
Run Code Online (Sandbox Code Playgroud)

请注意,如果您想要一个单独的函数来处理

void function(const char*& t1, const char*& t2);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,只需添加这样一个函数并依靠重载来发挥它的魔力。一般来说,当您发现自己在编写显式函数模板特化时,很可能您真正想做的可能只是使用重载。另请参阅模板专业化 VS 函数重载这篇文章(旧的,但仍然像以前一样真实)了解更多信息……