Ответ 1
Перегрузка для массивов:
template< class T, std::size_t N >
constexpr T* begin( T (&array)[N] );
И std::declval<int[3]>()
дает вам int(&&)[3]
, который не соответствует этой перегрузке. Он также не соответствует нормальной перегрузке контейнера, потому что это SFINAE-ed при наличии c.begin()
. Таким образом, у вас нет соответствующей функции.
Вместо этого вам нужно передать ссылку lvalue на массив на begin()
, чтобы вернуть итератор. Таким образом, либо вам нужно вручную указать ссылку на lvalue, когда вы используете свой псевдоним:
template <class T>
using type = decltype(std::begin(std::declval<T>()));
using arr = type<int(&)[3]>; // int*
или сам псевдоним предоставляет ссылку lvalue для вас:
template <class T>
using type = decltype(std::begin(std::declval<T&>()));
using arr = type<int[3]>; // int*
Первое кажется мне более правильным, но YMMV.