c – 当函数参数是const引用T时,为什么T’的模板参数推导会跳过
让我们考虑一下这些定义:
/*** 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 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正在做的事情(即推导为非const). 因此,我认为后来的行为是标准的,但是理由是什么?它看起来不像指针一样令人惊讶. 编辑:在评论之后,我将在这里报告与此行为相关的CWG问题的指针,他实际发布的指针作为对this answer的评论(回答实际上提出了这个新问题…… C感觉就像一个深隧道) > CWG 1059 解决方法
使用此函数模板原型:
template <typename T> void func(const T& a); 在第一个示例中,类型推导的工作原理如下: const int* ip; func(ip) => func<const int*>(const (const int*)& a) ^^^^^^^^^^ ^^^^^^^^^^ 注意:这是伪代码.完整类型是const int * const&. 请注意,const int仍然是const int,但*变为* const. 这是因为const int *只是一个常规的,可变的,非易失性的指针.这只是一个*.它所指的是无关紧要的. 但在第二个例子中,你有: const int ia[3]; func(ia) => func<int[3]>(const (int[3])& a) ^^^^^^ ^^^^^^ 注意:这是伪代码.真实的类型是const int(& a)[3]. 因此类型推导在两种情况下都是相同的,丢弃外部const. 碰巧const数组与const元素数组相同. 写这样的类型可能会有所帮助: template <typename T> func(T const & a); int const * ip; func(ip) => func<int const *>(int const * const & a) int const ia [3]; func(ia) => func<int [3]>(int const (& a) [3]) 在第二个例子中,const似乎“移动”从应用于数组到应用于元素.这是因为你不能真正拥有const数组,只有const数组的数组. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |