C++ std::remove_const如何在内部工作

C++ std::remove_const如何在内部工作,c++,std,typetraits,C++,Std,Typetraits,案例1 std::remove_const的可能实现是 template< class T > struct remove_const { typedef T type; }; template< class T > struct remove_const<const T> { typedef T type; }; 当我使用它们时 std::remove_const<int> // use the first version s

案例1 std::remove_const的可能实现是

template< class T > struct remove_const          { typedef T type; };
template< class T > struct remove_const<const T> { typedef T type; };
当我使用它们时

std::remove_const<int> // use the first version
std::remove_const<const int> // use the second version
案例2 如果我评论第二个版本

template< class T > struct remove_const          { typedef T type; };
//template< class T > struct remove_const<const T> { typedef T type; };
并使用它们

std::remove_const<int> // use the first version
std::remove_const<const int> // use the first version
在案例1中,编译器如何决定为const int选择第二个版本

const T版本比泛型版本更专业,因为如果类型匹配const T,则也匹配泛型T;int匹配T,但不匹配常数T

规则是,如果一个类型匹配两个或多个版本,编译器必须选择更专业的版本。

这不是模板的两个不同版本。这是一个单一的模板,您称之为第一个版本,定义了一个专门化,您称之为第二个版本

因此,当您使用模板时,它总是首先查找模板的定义,然后查找与您正在使用的类型签名匹配的模板的先前存在的专门化和实例化。如果它找到了匹配的专门化或实例化,它就会使用它。只有当没有现有的专门化或实例化时,它才会恢复模板

因此,当您说remove_const时,它与模板匹配,但与专门化不匹配,因此它实例化了模板。remove_const匹配模板,也匹配专门化,因此它使用专门化,专门化也是一个模板,因此需要实例化,但这是次要的


使第二个版本成为专门化而不是新模板的是名称remove\u const之后的列表。

有些关联:我想你是在问部分模板专门化是如何工作的。这很复杂,但这个wiki是一个不错的概述:。简而言之,const int比plain-old-T更接近const T,因此它更受欢迎。@TravisGockel感谢您的链接。我已经阅读了有关模板专门化的内容。但我看到的例子是,对完全不同的类型使用专门化,例如int、float、short,但不使用密切相关的类型,例如int和const int。感谢您提供的信息,当然有一个标准。确切地说是ISO标准。虽然官方出版物是专有的,但发布前的最后草稿可供公众使用,并且与完成的文档几乎相同。请注意,您不应该在代码中真正使用remove_const。百分之九十九,如果你是,那么你可能做错了什么。