【发布时间】:2015-06-18 14:31:02
【问题描述】:
我正在通过新的 C++14 运行时大小的数组测试 type_traits 标头中的一些工具,请考虑以下代码:
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]'
而且我注意到运行时大小数组上的大小变量似乎与类型相关(而不是 mismatched types 'T*' and 'int [5]' 我们得到的是 mismatched types 'T*' and 'int [ s]') 这看起来很奇怪。
那么,问题是什么?
- 为什么我在这个运行时大小的数组中没有得到数组到指针的衰减?
- 变量是否用于调整运行时大小数组的大小是运行时大小数组类型的一部分还是我误解了错误?
【问题讨论】:
-
请注意,您使用带有
int a[s];的VLA扩展 -
许多编译器标志或代码规范禁止使用运行时大小的数组。 (例如,我知道带有警告标志的 G++ 禁止它)您的编译器可能拒绝将其用作模板。
-
为了扩展 Jarod42 的评论,提出了运行时大小的数组,但最终并未包含在最终的 c++14 标准中。
-
我的错!我真的认为运行时大小的数组包含在 C++14 中(这就是我添加 C++14 标记的原因)。无论如何它不会改变问题:为什么 VLA 在这个例子中不会衰减到指针?
-
它是否适用于精确大小的数组?比如你用
a[5];而不是a[s];来测试它?
标签: c++ arrays c++14 variable-length-array