Как передать константу в мой метод добавления класса DynamicArray

0

Мой DynamicArray в значительной степени является ArrayList. Я хочу, чтобы пользователи имели непрерывный блок памяти, где элементы один за другим, и при необходимости есть дополнительное пространство. Единственная проблема, с которой я столкнулся, заключалась в хранении ints/floats/bools и т.д. Я решил сделать свой _array T **, чтобы я мог их хранить.

Тем не менее, у меня есть немного проблем с передачей констант в мой метод добавления DynamicArray. Мне нужно сохранить значения в переменной, прежде чем передавать их, иначе я получаю эту ошибку:

    g++ main.cpp -Wall -Werror -std=c++0x

    main.cpp: In function ‘int main():
main.cpp:14:21: error: no matching function for call to ‘triforce::DynamicArray<std::basic_string<char> >::add(const char [5])
main.cpp:14:21: note: candidates are:
DynamicArray.h:150:10: note: bool triforce::DynamicArray<T>::add(T&) [with T = std::basic_string<char>]
DynamicArray.h:150:10: note:   no known conversion for argument 1 from ‘const char [5] to ‘std::basic_string<char>&
DynamicArray.h:176:10: note: void triforce::DynamicArray<T>::add(uint, T&) [with T = std::basic_string<char>, uint = unsigned int]
DynamicArray.h:176:10: note:   candidate expects 2 arguments, 1 provided

Мой DynamicArray имеет переменную T ** с именем _array.

/**
144      * @brief Adds an element to the end of the array. The array will double in size,
145      * if needed.
146      * @param element The element to be added to the array.
147      * @returns Returns if the element was added successfully.
148      */
149     template<class T>
150     bool DynamicArray<T>::add(T& element)
151     {
152         if(_array == NULL)
153         {
154             errorMsg("Cannot add to null array");
155             return false;
156         }
157 
158         if(_size == _capacity)
159         {
160             increaseCapacity(_capacity * 2);
161         }
162 
163         _array[_size] = &element;
164         _size++;
165 
166         return true;
167     }

Это работает:

13     string val1 = "val1";
 14     array.add(val1);

Это не работает

13     string val1 = "val1";
 14     array.add("val1");

Как я могу это сделать, чтобы эта функция могла принимать константы, например, просто передать 1 или строку "привет", не помещая сначала в переменную? Я попытался поставить параметр const в параметр, но это тоже не сработало.

Теги:

2 ответа

1
Лучший ответ

В приведенном ниже примере:

#include <type_traits>

template <class T>
void foo( T& arg )
{
  static_assert( std::is_same<T&, const char(&)[6]>::value, "Must be same" );
}

int main()
{
  foo( "Hallo world" );
  return 0;
}

тип выводится как const char [6]. затем становится ссылкой на массив и поэтому имеет тип:

const char (& array) [6]

Имя массива (без квалификации с помощью оператора []) распадается для ввода char * или в этом случае const char *:

_array[_size] = &element;

поэтому, беря его адрес, тип rhs здесь выше становится const char *, и невозможно присвоить переменную типа const char * переменной типа char & (которая возвращается _array [size].

Вы можете исправить это следующим образом:

template<class T>
void DynamicArray<T>::add( const T& element )
{
  if(_size == _capacity)
  {
    increaseCapacity(_capacity * 2);
  }
  _array[_size] = element;
  _size++;
}

//------ Added code --------
template<class T>
  template <int N> 
void DynamicArray<T>::add( const T (&array) [N] )
{
  for( std::size_t i = 0; i < N; ++i )
  {
    //Calls your add per element...
    add( array[i] );
  }
}

Обратите внимание, что вы не сможете использовать std :: string в приведенном выше коде. Для этого потребуется другая перегрузка. Также обратите внимание, что мои функции не имеют типа возврата (как и вы). Тип возврата не имел никакого смысла в вашем коде, поскольку любые ошибки (в результате, например, динамического распределения) были бы выброшены.

Наконец, как упоминалось в другом месте, приведенный здесь код просто написан для понимания понятий. На самом деле можно использовать std :: vector, который, конечно, уже является динамическим массивом.

  • 0
    Я пытался попробовать ваше решение с помощью int, но я получил сообщение об ошибке: _array [_size] = element; Так что, если _array - это T **, разве это не должно быть хорошо? Элемент является копией адреса 1. Мой вызов: array.add (1);
  • 0
    Все зависит от того, какой тип вы создали для своего класса. Если тип DynamicArray - char, и вы использовали T &, а не T, это означает, что компилятору необходимо преобразовать литерал, а временный не может привязаться к ссылке на l-значение:
Показать ещё 7 комментариев
0

Третья линия примечания объясняет проблему:

DynamicArray.h:150:10: note: no known conversion for argument 1 from 'const char [5] to 'std::basic_string<char>&

Итак, ваш DynamicArray<string> пытается преобразовать строковый литерал в std::string &, и нет никакого способа сделать это.

Вы можете сделать так, как вы пробовали, создать string перед рукой или изменить метод add() чтобы не использовать ссылку.

 template<class T>
 bool DynamicArray<T>::add(T element)
 {
     //...

Таким образом, копия сделана для вас в стеке, инициализированная строковым литералом, который будет передан его конструктору.

  • 0
    Единственная проблема с передачей по значению - это сохранение их в моем массиве _array. Если я сохраню ссылку на элемент, элемент просто не выскочит из стека? Когда я передаю значение, я всегда получаю максимальное значение int, когда выводю все элементы в свой DynamicArray. Также, как Vector позволяет передавать константу с этой сигнатурой: const value_type & val
  • 0
    Вы не показываете достаточно кода в своем вопросе для меня, чтобы поместить любой из ваших вопросов в контекст.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню