模板参数推导过程中会发生什么?

时间:2019-03-17 08:06:34

标签: c++ templates

template <typename T>
// 1:
void compare(T, T) {}

int main{
    compare("123", "45");
}
// T is const char *

// 2:
void compare(T *, T *) {}
// T is const char

// 3:
void compare(const T *, const T *) {}
// T is char

// 4:
void compare(const T, const T) {}
// T is const char *

1:

我的问题是根据我完全理解的1,2,3模式 为什么T变成它的样子。而第4码中的T不是我假设的char *

2:

为什么第一个代码和第4个代码产生相同类型的T。

3:

我可以使用reference中的const char *作为compare中的参数

3 个答案:

答案 0 :(得分:2)

  

我的问题是根据1,2,3的模式,我可以完全理解为什么T变成它的样子。而第4码中的T不是我假定的char *。

因为您被误导了以识别错误的模式。这是为什么“前导const误导”的一个示例。模板与宏不同,const在左侧的放置并不意味着它适用于char。它适用于整个参数类型,并且由于参数将是指针(由于将文字作为参数给出),因此综合函数将如下所示:

void compare(char const* const, char const* const) {}

这就是为什么许多C ++程序员(包括我自己)都喜欢使用cv-qualifers不同位置的原因。您的选项3和4会这样写:

void compare(T const *, T const *) {}
// T is char

// 4:
void compare(T const, T const ) {}
// T is const char *

它更一致,因为const始终适用于它左边的内容(如果有的话,否则会有一个异常,并且是一个令人困惑的异常)。而且,这也使人们清楚地知道了(无论如何,IMO)当推论结束后,什么将是常量。

答案 1 :(得分:1)

  

第4个代码中的T不是我假定的char *

请注意,在第四代码中,const直接在T上限定。当推导出T作为指针时,则const T表示const指针,而不是指向const的指针。因此,将T推导为const char*,第四个compare的自变量将为const char * const

让我们假设将T推导出为char *,那么const T将是char * const(即指向非const的{​​{1}}指针const),显然不是预期的参数类型。

  

我可以使用对char的引用作为const char *中的参数

我不确定我是否正确理解了您的问题,是的,您可以编写类似compare的内容以将其更改为通过引用,但是还要注意void compare(const T&, const T&) compare("123", "45");被推导为数组类型(在这种情况下,推论实际上将失败,因为T"123"不是同一数组类型),不会发生数组到指针的衰减。这可能不是您所期望的。

答案 2 :(得分:1)

compare的调用获取字符串文字,其类型为const char *;

  

1:我的问题是根据1,2,3的模式,我可以   完全理解为什么T变成它的样子。   第4个代码不是我假定的char *。

const T中,常量引用T,即const char*。 const in const char*表示字符。 const的两种情况涉及不同的事物。使用const T x,我们无法更改x,即指针x本身。使用const char* x,我们可以更改指针,但不能更改x指向的字符。

  

2:为什么第一个代码和第4个代码导致相同类型的   T。

请参阅上面的答案。 const T中的const对于调用者来说是多余的。调用者不在乎实现是否会更改其指针副本。只有实现才在乎。

  

3:我可以在compare中使用const char *的引用作为参数吗?

当然,只需编写const T&const char*const&(从右到左读取:对指向字符常量的常量指针的引用)