让我们考虑一下这些定义:
/*** 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
So T
实际上被推导为指向常量整数的指针。参数是对 const 的引用这一事实不会改变推论,这是人们所期望的,因为指针的常量是低级的。
但使用 const 数组
尽管如此,如果执行以下语句:
const int ia[3] = {3, 2, 1};
func(ia);
输出是:
Deduced type for T is: 4TypeI**A3_i**E
So T
实际上被推导出为 3 的数组non-常量整数。事实上,参数是对 const 的引用确实改变了的扣除,就好像const
正在滑入数组元素。
实际上,18 之前的 CL 版本都在推导T
因为 3 个常量整数的数组是我期望的标准,但似乎自 v19 以来它收敛到 GCC 和 Clang 正在做的事情(即推导为non-const).
因此,我认为后来的行为是标准的,但这是基本原理吗?它的行为与指针不同,这似乎令人惊讶。
Edit:下列的dip评论,我将在这里报告与此行为相关的 CWG 问题的指针,他实际上作为评论发布的指针这个答案 https://stackoverflow.com/a/30866205/1027706(实际上提出了这个新问题的答案...... C++ 感觉就像一条很深的隧道)
- CWG 1059 http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1059
- CWG 1610 http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#1610
- CWG 112 http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#112