The following program is, as expected, accepted by both GCC, Clang and MSVC (for various compiler and language versions):
// #g.1: rvalue reference function parameter
constexpr bool g(int&&) { return true; }
// #g.2: const lvalue reference function parameter
constexpr bool g(int const&) { return false; }
static_assert(g(0), ""); // OK: picks #g.1
The similar case but for overloads over an array {rvalue, const lvalue} reference parameter is, however, rejected by GCC, whilst it is accepted by Clang and MSVC:
#include <cstddef>
// #f.1: rvalue ref overload
template<std::size_t size>
constexpr bool f(int (&&)[size]) { return true; }
// #f.2: lvalue ref overload
template<std::size_t size>
constexpr bool f(int const (&)[size]) { return false; }
static_assert(f({1, 2, 3}), ""); // Clang: OK (picks #f.1)
// MSVC: OK (picks #f.1)
// GCC: Error (picks #f.2)
DEMO.
At first glance this looks like a GCC bug, but I'd like to be sure.
Question
- Which compiler(s) is(/are) right here?