让我们考虑这些定义:
/*** full type information with typeid ***/
template <class> class Type{};
template <class T> std::string typeStr()
{ return typeid(Type<T>).name(); }
/*** function template for parameter deduction ***/
template <class T> void func(const T &a)
{
std::cout << "Deduced type for T is: " << typeStr<T>() << std::endl;
std::cout << "\targument type is: " << typeStr<decltype(a)>() << std::endl;
}
带有指向 const 的指针
如果执行以下语句:
const int i=5, *ip=&i;
func(ip);
输出是:
Deduced type for T is: 4TypeI**PKi**E
所以T
实际上被推断为一个指向一个常量整数的指针。参数是对 const 的引用这一事实不会改变推论,这是人们所期望的,因为指针的 const 是低级的。
但有 const 数组
尽管如此,如果执行以下语句:
const int ia[3] = {3, 2, 1};
func(ia);
输出是:
Deduced type for T is: 4TypeI**A3_i**E
所以T
实际上被推导出为 3 个非常量整数的数组。参数是对 const 的引用这一事实确实改变了推论,就好像它const
滑入了数组元素一样。
实际上,最多 18 个版本的 CL 推断T
为 3 个 const 整数的数组是我期望的标准,但似乎自 v19 以来它收敛到 GCC 和 Clang 正在做的事情(即推断为非常量)。
因此,我认为后来的行为是标准的,但这是基本原理吗?它的行为与指针不同,这似乎令人惊讶。
编辑:在发表评论之后,我将在这里报告与此行为相关的 CWG 问题的指针,他实际上作为对此答案的评论发布的指针(实际上提出了这个新问题的答案...... C++ 感觉就像一条深隧道)