[英]As template type argument, why doesn't type[N] match its specialized version -— template<class T> class S<T[]>
这是一个演示(缩写为cppreference ):
#include <iostream>
#include <type_traits>
template<class T>
struct is_array : std::false_type {};
template<class T>
struct is_array<T[]> : std::true_type {};
class A {};
int main()
{
std::cout << std::boolalpha;
std::cout << is_array<A>::value << '\n';
std::cout << is_array<A[]>::value << '\n';
std::cout << is_array<A[3]>::value << '\n';
}
输出( live demo
):
false
true
false
我们可以看到is_array<A[3]>
被解析为主要特化: template<class T> struct is_array
,而不是template<class T> struct is_array<T[]>
。
这让我很困惑。 当然我知道std::is_array
的完整实现(如cppreference中所述)还包含length的特殊化: template<class T, std::size_t N> struct is_array<T[N]>
和std::is_array<A[3]>
[3]>将按预期解决此专业化问题。 但这无法解释最重要的演示,对吧?
搜索之后,我找到了这个帖子 ,但这是一个关于如何 ,而不是为什么的问题 。 但在评论中 , @ Steve Jessop提到:
我不完全确定,但我认为你在那里写的是对未知大小的数组的专门化。 这是一个不完整的类型,但可以用于其他TU将提供的数组的extern声明。
它似乎与它是一个不完整的类型有关 :
声明的数组对象类型可能是未知边界的数组,因此在翻译单元中的某个点处不完整,稍后会完成; 这两个点的数组类型(“T的未知边界数组”和“NT数组”)是不同的类型。 指向未知边界数组的指针类型,或者由typedef声明定义为未知边界数组的类型的指针类型无法完成
extern int arr[]; // the type of arr is incomplete
int arr[10]; // now the type of arr is complete
[basic.types] / 6没有提供任何其他有用的信息。
我注意到规范中的示例中有一个错误,这让我想到它可能不是关于特化,而是因为A[3]
不能匹配struct is_array<T[]>
。 这就是编译器似乎肯定的:
#include <iostream>
#include <type_traits>
template<class T>
struct is_array<T[]> : std::true_type {};
class A {};
int main()
{
is_array<A[3]> *a; // error
is_array<A[3]> b; // error
}
以上是我自己试图解决的问题,没有成功。 所以我在这里找到一个彻底的答案。
简短的回答在你自己引用的段落中:
声明的数组对象类型可能是未知边界的数组,因此在翻译单元中的某个点处不完整,稍后会完成; 这两个点的数组类型(“T的未知边界数组”和“NT数组”)是不同的类型 。 指向未知边界数组的指针类型,或者由typedef声明定义为未知边界数组的类型的指针类型无法完成
那些是不同的类型。 虽然您可以在第一个声明点之后“修复”数组对象的类型,但它仍然不会改变那些不同类型的事实。 他们的行为不同。 例如:
using AI = int[];
using AC = int[3];
AI a1 = {1, 2, 3, 4};
AC a2 = {1, 2, 3, 4}; // error
可以使用初始化程序{1, 2, 3, 4}
初始化对象a1
。 我们看到I类型别名为AI
有点像auto
,初始化器可用于帮助推断完整类型。
另一方面, a2
导致错误,因为我提供了太多的初始化器。 如果我提供的太少,我的数组中仍然有3个元素,未明确初始化的元素将默认初始化。
我希望你现在确信那些确实是非常不同的类型。 所以作为模板参数,它们不应该匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.