我一直在阅读有关删除类型为here的引用的信息。
它给出以下示例:
#include <iostream> // std::cout
#include <type_traits> // std::is_same
template<class T1, class T2>
void print_is_same() {
std::cout << std::is_same<T1, T2>() << '\n';
}
int main() {
std::cout << std::boolalpha;
print_is_same<int, int>();
print_is_same<int, int &>();
print_is_same<int, int &&>();
print_is_same<int, std::remove_reference<int>::type>(); // Why not typename std::remove_reference<int>::type ?
print_is_same<int, std::remove_reference<int &>::type>();// Why not typename std::remove_reference<int &>::type ?
print_is_same<int, std::remove_reference<int &&>::type>();// Why not typename std::remove_reference<int &&>::type ?
}
type
特性中的std::remove_reference
是从属类型。
可能的实现
template< class T > struct remove_reference {typedef T type;};
template< class T > struct remove_reference<T&> {typedef T type;};
template< class T > struct remove_reference<T&&> {typedef T type;};
但是为什么不使用typename std::remove_reference</*TYPE*/>::type
?
type
特性中的std::remove_reference
是从属类型。
[不,这里不是dependent names。模板参数已明确指定为int
,int&
和int&&
。因此,此时类型是已知的。
另一方面,如果您将std::remove_reference
与模板参数一起使用,例如
template <typename T>
void foo() {
print_is_same<int, typename std::remove_reference<T>::type>();
}
然后您必须使用typename
来确定typename
是一种类型,因为您的表达式现在取决于模板参数std::remove_reference<T>::type
。
简而言之,您需要T
以确保编译器具有以下功能:>
typename
确实是一种类型。让我们考虑其他模板
的方向提供专业化服务,该怎么办?std::remove_reference<int>::type
这里
template <typename T> struct foo { using type = int; };
是一种类型。但是,如果有人按照
foo::type
现在
template <> struct foo<int> { int type; };
不是类型,而是type
。现在,当您在模板中使用foo时:
int
您必须确保编译器确实
template <typanem T> struct bar { using type = typename foo<T>::type; };
是一种类型,而不是其他类型,因为仅查看foo<T>::type
(和主模板bar
),编译器就无法知道。
但是,在您的foo
中,main
不依赖于模板参数,因此编译器可以轻松地检查它是否为类型。
关键字typename