繁体   English   中英

作为模板类型参数,为什么不键入[N]匹配其专用版本 - 模板 <class T> S级 <T[]>

[英]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
}

demo


以上是我自己试图解决的问题,没有成功。 所以我在这里找到一个彻底的答案。

简短的回答在你自己引用的段落中:

声明的数组对象类型可能是未知边界的数组,因此在翻译单元中的某个点处不完整,稍后会完成; 这两个点的数组类型(“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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM