1) Почему преобразование не-const в const здесь не выполняется автоматически?
Поскольку std::array<T, Dim> const
и std::array<T const, Dim>
- это разные типы и, как говорят мои clang ++, "нет известного преобразования из 'array<int, [...]>
' в 'array<const int, [...]>
'"
2) Можно ли это исправить, не вводя третью неконстантную версию конструктора?
А как насчет конструктора шаблонов
template <typename T>
A (std::array<T, 2> const &) {}
где T
может совпадать с int
и int const
?
Если вы хотите навязать, что T
- это всего лишь int
или int const
(а не, например, long const
), вы можете сделать это через SFINAE с чем-то вроде
template <typename T>
A (std::array<T, 2>,
std::enable_if_t<std::is_same<T const, int const>{}> * = nullptr)
{ }
Так что вы можете иметь
std::array<int, 2> a = {{0}};
std::array<int const, 2> b = {{0}};
std::array<long const, 2> c = {{0}};
const A x(a); // compile
const A y(b); // compile
const A z(c); // compilation error
3) Также помогает изменение конструктора, чтобы он принимал gsl :: span вместо std :: array, но также выглядит как избыточное убийство
Извините, но я не понимаю третий вопрос (?) (И я не знаю gls::span
)