C++ — вызов невариативного конструктора в шаблоне класса без приведенияC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 C++ — вызов невариативного конструктора в шаблоне класса без приведения

Сообщение Anonymous »


Данный шаблон класса cArray с двумя конструкторами:
[*]тот, который принимает один параметр std::size, и [*]тот, который принимает любое количество аргументов (при условии, что они могут быть созданы из T). Вопрос
Как изменить cArray, чтобы он использовал первый конструктор (с одним аргументом) при задании одного целочисленного литерала без приведения к std::size_t ?
[*]Какой вывод здесь (с концептуальной точки зрения)?
Пример:
[*]
cArray arr1(7): вызывает конструктор с переменным числом аргументов, в результате чего создается cArray, содержащий один элемент (7). [*]cArray arr1((std::size_t)7): ведет себя корректно (но приведение всегда неудобно).
Код
богболт

cArray.hpp

шаблон класс cArrayIterator; шаблон класс cArray { публика: используя value_type = T; используя array_type = cArray; используя size_type = std::size_t; используя разницу_типа = std::ptrdiff_t; используя ссылку = тип_значения&; используя const_reference = value_type const&; используя указатель = тип_значения*; используя const_pointer = value_type const*; используя итератор = cArrayIterator; использование const_iterator = cArrayIterator; cArray(std::size_t _size) { если (_size > 0) { м_размер = _размер; m_arr = новый T[_size]; } еще { throw std::runtime_error("СДЕЛАТЬ: длина массива не может быть равна 0!"); } } шаблон требуется (std::constructible_from&&...) cArray(Элементы&&... es) : m_size{ sizeof...(es) } , m_arr{new T[sizeof...(es)] { es... } } {} // специальные функции-члены cArray(const cArray& _other) { m_size = _other.size(); m_arr = новый T[m_size]; std::copy_n(_other.m_arr, m_size, m_arr); } cArray(cArray&& _other) noException : m_size(std::exchange(_other.m_size, 0)) , m_arr(std::exchange(_other.m_arr, nullptr)) {} ~cArray() { удалить [] m_arr; } cArray& оператор=(const cArray& _other) { удалить [] m_arr; m_size = _other.m_size; m_arr = новый T[m_size]; std::copy_n(_other.m_arr, m_size, m_arr); вернуть *это; } cArray& оператор=(cArray&& _other) noException { удалить [] m_arr; m_size = std::exchange(_other.m_size, 0); m_arr = std::exchange(_other.m_arr, nullptr); вернуть *это; } constexpr value_type& at (const size_type _index) { если (_index < m_size) { вернуть m_arr[_index]; } еще { throw std::out_of_range("СДЕЛАТЬ: индекс выходит за пределы."); // ЧТО СДЕЛАТЬ: пользовательское исключение } } constexpr const_reference back() const noException { вернуть m_arr[m_size - 1]; } constexpr const_reference front() const noException { вернуть m_arr[(size_type)0]; } итератор начало() { вернуть итератор(*это, 0); } конец итератора() { вернуть итератор(*this, m_size); } const_iterator начало() константа { return const_iterator(*this, 0); } const_iterator end() const { return const_iterator(*this, m_size); } constexpr size_type size() const noException { вернуть м_размер; } constexpr T& оператор[](const size_type _pos) { вернуть m_arr[_pos]; } constexpr const T& оператор[](const size_type _pos) const { вернуть m_arr[_pos]; } частный: друг cArrayIterator; друг cArrayIterator; std::size_t m_size; Т*м_арр; }; шаблон cArray(const T&, const T&) -> cArray; шаблон явный cArray(T&&, T&&)->cArray; шаблон класс cArrayIterator { используя array_type = std::conditional_t; публика: используя value_type = std::remove_const_t;; используя value_const_type = std::add_const_t; использование iterator_type = cArrayIterator; использование iterator_const_type = cArrayIterator; используя size_type = std::size_t; используя разницу_типа = std::ptrdiff_t; используя ссылку = тип_значения&; используя const_reference = value_type const&; используя указатель = тип_значения*; используя const_pointer = const value_type*; используя iterator_category = std::random_access_iterator_tag; // конструктор(ы) явный cArrayIterator(array_type& _array, size_type const _index) : m_array_ref(_array) , m_index(_index) {} автоматический оператор(const cArrayIterator&) const = по умолчанию; iterator_type&operator=(const cArrayIterator& _other) { m_array_ref = _other.m_array_ref.get(); m_index = _other.m_index; вернуть *это; } iterator_type&operator=(cArrayIterator&& _other) noException { // Копируем указатель данных и его длину из // исходный объект. m_array_ref = _other.m_array_ref; m_index = _other.m_index; // Освободите указатель данных из исходного объекта, чтобы // деструктор не освобождает память несколько раз. _other._data = nullptr; _other._length = 0; m_array_ref = std::move(_other.m_array_ref); m_index = _other.m_index; вернуть *это; } booloperator==(iterator_type const& _other) const { return ((m_array_ref.get().m_arr == _other.m_array_ref.get().m_arr) && (m_index == _other.m_index)); } логический оператор!=(iterator_type const& _other) const { return ((m_array_ref.get().m_arr != _other.m_array_ref.get().m_arr) || (m_index != _other.m_index)); } const_reference оператор*() const { // убеждаемся, что массив находится в пределах границ if ((m_index < 0) || (m_index >= m_array_ref.get().m_size)) { throw std::logic_error("СДЕЛАТЬ: невозможно разыменовать итератор"); } вернуть m_array_ref.get().m_arr[m_index]; } оператор указателя->() const { // убеждаемся, что массив находится в пределах границ если ((m_index < 0) || (m_index >= m_array_ref.get().m_size)) { throw std::logic_error("СДЕЛАТЬ: невозможно разыменовать итератор"); } return &(m_array_ref.get().m_arr[m_index]); } тип_итератора и оператор++() { если (m_index >= m_array_ref.get().m_size) { throw std::out_of_range("СДЕЛАТЬ: индекс выходит за пределы!"); } м_индекс++; вернуть *это; } тип_итератора оператор++(int) { iterator_type temp = *this; +*** это; температура возврата; } тип_итератора и оператор --() { если (m_index = m_array_ref.get().m_size) { throw std::out_of_range("СДЕЛАТЬ: Итератор не может быть увеличен за пределами диапазона"); } м_индекс = следующий; вернуть *это; } тип_итератора и оператор-=(константный тип разницы_тип_смещение) { тип_разницы следующий = m_index - _offset; если (следующий > 0) { throw std::out_of_range("СДЕЛАТЬ: Итератор не может быть увеличен за пределами диапазона"); } м_индекс = следующий; вернуть *это; } тип_значения& оператор[](size_type _index) const { если (_index >= m_array_ref.get().m_size) { throw std::out_of_range("СДЕЛАТЬ: индекс вне диапазона."); } return (m_array_ref.get().m_arr + _index); } частный: std::reference_wrapper m_array_ref; размер_типа м_индекс = 0; }; cArrayImpl.cpp

класс шаблона DArray; класс шаблона DArray; main.cpp

#include #include #include ".\cArray.hpp" #include ".\cArray_tests.cpp" #include ".\cArrayImpl.cpp" интервал main(int argc, char ** argv) { cArray arr1((std::size_t)10); std::cout
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»