为何数组类型的prvalue无法初始化同类型对象?关于C++编译器拒绝特定数组初始化代码的标准合规性问询
T arr = T{1,2}; (where T = int[2]) fail to compile in Clang and GCC? First off, let's clarify the code you're working with:
int main(){ using T = int[2]; T arr = T{1,2}; }
Clang and GCC both reject this with errors along the lines of "cannot initialize array element of type 'int' with an rvalue of type 'int*'" or "array initializer must be an initializer list". This isn't a compiler bug—it's a result of several overlapping C++ standard rules that are easy to overlook, even if the clauses you referenced don't explicitly call this out.
Here's the breakdown:
1. Array prvalues immediately decay to pointers
Per the [conv.array] section of the C++ standard:
An lvalue or rvalue of type "array of N T" or "array of unknown bound of T" can be converted to a prvalue of type "pointer to T". This conversion is called array-to-pointer decay.
When you write T{1,2} (with T = int[2]), this does create an array-type prvalue—but it's immediately converted to a int* prvalue (pointing to the first element of the temporary array). The only exceptions to this decay are contexts where the array type is explicitly preserved, like in decltype(T{1,2}) or when passing to a function that takes an array by reference.
2. Copy initialization of arrays doesn't support pointer values
Your code uses copy initialization (the = syntax) for an array. For array-type objects, the standard restricts valid initializers for copy initialization:
- For character/wide-character arrays, you can use a string literal (e.g.,
char buf[] = "test";); - For all other arrays, the only valid initializer is an initializer list (e.g.,
int arr[] = {1,2};).
Since T{1,2} decays to an int*, you're trying to initialize an array with a pointer value—which the standard explicitly disallows. That's why the compiler throws an error.
3. The standard does prohibit this (indirectly)
The clauses you cited ([dcl.init.general-15.9] and [basic.lval-1.2]) don't directly forbid this, but combine with other rules:
- Arrays have no copy constructor and can't be moved (they're non-copyable objects by design);
- The automatic decay of array prvalues turns your initializer into a pointer, which isn't a valid array initializer;
- Even if you tried to use
std::move(T{1,2})to create an xvalue, array xvalues also decay to pointers, so this doesn't help.
How to fix this
If you want to initialize the array with those values, use direct initialization instead (no =):
int main(){ using T = int[2]; T arr{1,2}; // Valid: direct list initialization of the array }
Or, if you specifically want copy-like behavior, switch to std::array (which is a copyable wrapper for arrays):
#include <array> int main(){ using T = std::array<int, 2>; T arr = T{1,2}; // Valid: std::array supports copy initialization }
内容的提问来源于stack exchange,提问作者xmh0511

