3

我正在研究一个函数的模板。为了简化,假设它看起来像这样:

template < typename T >
void f(const T & x)
{
    cout << "generic case" << endl;
    cout << x << endl;
}

我一直认为 C 字符串不能用作模板参数参数。但以下实际上有效(使用 g++ 4.5.1):

f("hello world");

所以我的问题是:我什么T时候打电话f("hello world")

我试图专注于看看到底发生了什么。例如,因为char[]const char*看了这个(这显然不起作用):

template < typename T >
void f(const T & x)
{
    cout << "generic case" << endl;
    cout << x << endl;
}
template <>
void f(const const char * T & x)
{
    cout << "char[] case" << endl;
    cout << x << endl;
}

并尝试了几种变体。它们都不起作用。

旁白:我的工作并不需要这个。我需要专门针对 T = "C-string" 的情况,所以我只写了另一个模板函数:

template < typename T >
void f(const T & x)
{
    cout << "generic case" << endl;
    cout << x << endl;
}
template < typename T >
void f(T x[])
{
    cout << "T[] case" << endl;
    cout << x << endl;
}

我只是在问,因为我很好奇到底发生了什么,为什么当我读到的内容说不能时,为什么允许 C 字符串作为模板参数。我一定误读/误解了一些关于模板的东西。

4

2 回答 2

3

没有 C 字符串类型。术语 C-string 定义内容,而不是类型。它指的是字符数组的一部分,其中某处有一个空字符,某些函数将其解释为字符串的结尾。

不过,您真正感兴趣的是字符串文字。字符串文字具有 type const char[N],其中 N 是字符串中的字符数,包括隐式空终止符。"hello world"类型也是如此const char[12]。您可以像这样专门针对它:

template<>
void f(const char(&x)[12])
{
   cout << "const char[12] case" << endl;
   cout << x << endl;
}

请注意,这仅涵盖大小为 12 的数组。但是,您可以重载(而不是专门化)所有f()大小的数组,如下所示:

template<size_t N>
void f(const char(&x)[N])
{
    cout << "const char[" << N << "] case" << endl;
    cout << x << endl;
}

另请注意,这些方法也将涵盖普通的命名数组。没有办法区分它们和字符串文字。

于 2013-03-28T04:37:31.203 回答
0

请注意,这也将作为 const char[N] 和 const char* 都可以推断,

template < typename T >
void f(const T* x)
{
    cout << "const char* case" << endl;
    cout << x << endl;
}

这里的特化是常量指针类型。

如果您需要基于 char 数组类型或指针类型的特化,您还可以使用简单的函数重载。

于 2013-03-28T05:48:55.910 回答