我正在测试type_traits
标题中的一些工具,而不是新的C ++ 14运行时大小的数组,请考虑以下代码:
int g[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
template <typename T> void print(T &t)
{
std::cout << "Type id: " << typeid(T).name() << '\n';
std::cout << "is_array: " << std::is_array<decltype(T)>::value << '\n';
std::cout << "is_pointer: " << std::is_pointer<decltype(T)>::value << '\n';
std::cout << "extent: " << std::extent<decltype(T)>::value << '\n';
}
int main()
{
print(g);
return 0;
}
静态大小的数组g
返回以下输出:
Type id: A11_i
is_array: 1
is_pointer: 0
extent: 11
未编号的名称A11_i
我假设 A 11 类型 int 的元素,所以所有这是正确的,但使用这个新代码:
void f(std::size_t s)
{
int a[s];
print(a);
}
int main()
{
f(5);
return 0;
}
我收到错误:
In function 'void f(std::size_t)':
error: no matching function for call to 'print(int [s])'
note: candidate is:
note: template<class T> void print(T&)
note: template argument deduction/substitution failed:
note: variable-sized array type 'int [s]' is not a valid template argument
我没想到size参数可以传递给模板但是我期待一个自动的数组到指针衰减。我猜这个论点T &
并不适合这种衰变,所以我试图将模板签名更改为:
template <typename T> void print(T *&t)
结果相似:
In function 'void f(std::size_t)':
error: no matching function for call to 'print(int [s])'
note: candidate is:
note: template<class T> void print(T*&)
note: template argument deduction/substitution failed:
note: mismatched types 'T*' and 'int [s]'
我注意到运行时大小的数组上的size变量似乎与类型相关联(而不是mismatched types 'T*' and 'int [
5
{{1}我们得到]'
mismatched types 'T*' and 'int [
s
)这看起来很奇怪。
那么,问题是什么?
答案 0 :(得分:3)
在模板参数推导期间,仅当函数模板参数的类型不是引用时才使用数组到指针的转换。
§14.8.2.1从函数调用中推导出模板参数 [temp.deduct.call] 强>
1通过比较每个函数来完成模板参数推导 模板参数类型(称之为
P
)的类型 相应的调用参数(称之为A
)如下所述。 [...]2如果
P
不是参考类型:
- 如果
A
是数组类型,则使用数组到指针标准转换(4.2)生成的指针类型代替A
类型扣除;否则,- [...]