运行时大小的数组和 pointer-decay

Runtime sized arrays and pointer-decay

我在新的 C++14 运行时大小的数组上测试 type_traits header 中的一些工具,考虑下面的代码:

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;
}

静态大小数组greturns输出如下:

Type id:    A11_i
is_array:   1
is_pointer: 0
extent:     11

未损坏的名称 A11_i 我假设它是 Array of 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

我没想到大小参数可以传递给模板,但我期待的是自动 array-to-pointer 衰减。我猜参数 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]') 这看起来很奇怪。

那么,问题是什么?

在模板参数推导期间,仅当函数模板参数的类型不是引用时才使用数组到指针的转换。

§14.8.2.1 Deducing template arguments from a function call [temp.deduct.call]

1 Template argument deduction is done by comparing each function template parameter type (call it P) with the type of the corresponding argument of the call (call it A) as described below. [...]

2 If P is not a reference type:

  • If A is an array type, the pointer type produced by the array-to-pointer standard conversion (4.2) is used in place of A for type deduction; otherwise,
  • [...]