2015-06-01 1 views
2

Так как в заголовке указано, что у меня есть эта проблема. Я реализую двусвязный список в качестве шаблона и на некоторых из функций, такой какшаблон return when Element является структурой

Element getFirst(); 
Element getLast(); 
Element getPosition(int position); 

Они должны возвращать элемент типа элемента. Проблема в том, что, если список пуст? Что я тогда верну? Я не могу вернуть 0 или некоторое целое число, потому что, если мой Элемент является структурой. Он будет сбой позже в коде. Каким должно быть мое возвращение? Я попытался создать пустую переменную типа Element и отправить ее, но это тоже не сработает. Любые идеи?

Я могу предоставить любой фрагмент кода, который вам нужен, или информацию. Просто спросите

+2

Вы можете выбросить исключение при попытке извлечь элементы из пустого списка –

+0

Можете ли вы изменить интерфейс? –

+0

Мой код не построен на исключениях.Это что-то быстро сделанное, мне нужно что-то вернуть – Charlotte45

ответ

5

Решение зависит от вас:

  1. Имейте неопределенное поведение, если функция вызывается на пустой контейнер. Вы должны четко зафиксировать эти случаи. В таком случае пользователь должен будет проверить, будет ли вызов функции действительным, например, с помощью метода empty. Это относится к std::vector::front.
  2. Выбросить исключение, такое как std::vector::at.
  3. Возвращение boost::optional в descriped в другой ответ
  4. возвращают указатель или итератор, как предложено в комментариях
  5. Поскольку вы не возвращаются ссылки на элементы, которые вы могли бы также вернуться по умолчанию построен объект типа T а, что в идеале был бы способ проверить, что он недействителен. Аналогично тому, что делает QHash::value.

В любом случае вам нужно делать чеки где-то в вашем коде.

+1

Как и в случае 3. верните указатель (как я полагаю, элемент Element выходит в OP-контейнере и никакой копии не требуется). – Jarod42

+0

Я попытался включить библиотеку fost optional и программа не узнает ее. #include "optional/optional.hpp" это то, что я пробовал – Charlotte45

+0

@ Jarod42 спасибо за tipp, я добавил его к ответу, включая итераторы. – mfuchs

2

Использовать boost::optional. Вы изменили бы тип возврата на boost::optional<Element>. boost::optional является contextually convertible to bool. Таким образом, пример использование будет:

if(yourList.getFirst()) 
    std::cout << "Found the first element." << std::endl; 
else 
    std::cout << "No first element exists." << std::endl; 

Под капотом boost::optional<T> поддерживает bool, показывающий, является ли объект инициализирован с действительным T. Конструктор по умолчанию создает объект optional<T>, помеченный как недействительный T.

+0

Хм, я проверю, как это возможно. Первый раз слышу об этом. Это что-то вроде авто? Я не могу использовать причину cout, потому что я пытаюсь реализовать структуру данных, которую я позже буду использовать для решения проблемы. – Charlotte45

+0

Или, может быть, просто 'Element *' – Jarod42

+1

в качестве примера: если вы измените свой тип возврата на 'boost :: optional ', вы можете вернуть 'int', как если бы вы обычно возвращали' int' или return 'boost :: none', что означает, что возвращаемое значение пуст. – dlavila

2

Есть несколько вариантов:

  • Обеспечить способ запроса, чтобы увидеть, если объект может поддерживать оп (например, empty).

  • Вернуть то, что может означать «пусто». Например, вы можете вернуть указатель (const), или optional<Element>.

Другой подход, который будет работать, но его следует избегать, - это исключение.

Смежные вопросы