On Thu, 10 Jun 2021 at 16:25, Vladimir Grigoriev <vlad.moscow@mail.ru> wrote:
Now let’s consider the following example.
 
void g( const int ( & )[][2] )
{
    std::cout << "void g( const int ( & )[][2] )\n";
}
void g( const int ( & )[2][2] )
{
    std::cout << "void g( const int ( & )[2][2] )\n";
}
 
//…
 
g( { 1, 2, 3 } );
 
The MS VS 2019 issues an error that it is unable to convert the initializer list for either function.
 
Is it a compiler bug or does it behave correctly? In the last case what is the explanation of such a behavior? 

Very interesting; this appears to be a compiler bug(s).

int const a[2][2] = {123}; // #1
int const (&b)[2][2] = {123}; // #2
int f(int const (&)[2][2]);
int i = f({123}); // #3

clang: accepts #1, #2
gcc: accepts #1
icc: accepts #1, #2, #3
MSVC: accepts #1

Per [dcl.init.general]/1 I'm fairly sure that icc is correct here; there's nothing about brace elision [dcl.init.aggr]/15 that restricts it being used in a function call [expr.call]/7.