Вяртанне NULL ў функцыі, якая павінна вяртаць вектар

У мяне ёсць функцыя з наступным загалоўкам:

std::vector MySewer::createCuttingArray(MyCloth** cloth, NxU32 startPoint, NxU32 endPoint)

Функцыя павінна вяртаць вектар, які змяшчае некаторыя цэлыя значэння. Але ёсць адна праблема: Калі радок не створаны правільна (ёсць спосаб, у якім гэта можа адбыцца), я хачу зрабіць нешта накшталт таго, што я зрабіў у Java і C#, каб вярнуць NULL. Але ад таго, што я бачу, у C ++, NULL вызначаецца як цэлы лік. Як я магу вярнуць сапраўдны NULL для вектара?

4
вы можаце вярнуць паказальнік.
дададзена аўтар Daniel A. White, крыніца
Вы можаце паглядзець у раздзеле «Дадатковыя» класа ўзмацнення. boost.org/doc/libs/1_53_0/ ЛИЭС/факультатыўны/DOC/HTML/index.html Я думаю, што станд :: неабавязкова плануецца C ++ 14, якія не дапамогуць вам цяпер.
дададзена аўтар jcoder, крыніца
Тры разы той жа адказ на працягу некалькіх секунд: D
дададзена аўтар SinisterMJ, крыніца
Ці пусты вектар
дададзена аўтар SinisterMJ, крыніца
Кінуць выключэнне замест гэтага?
дададзена аўтар syam, крыніца
Вы таксама можаце вярнуць пусты вектар ... і мець справу з ім так жа, як вы б мець справу з NULL - Edit: Double ... ніндзя
дададзена аўтар i Code 4 Food, крыніца
Я дала адказ ніжэй, але глядзі таксама пытанні, звязаныя stackoverflow.com/q/10371094/96780 і stackoverflow.com/q/7425241/96780 .
дададзена аўтар Daniel Daranas, крыніца
Вы можаце вярнуць пусты вектар.
дададзена аўтар selalerer, крыніца
Іншы спосаб справіцца з гэтым, каб вярнуць код памылкі (INT), і замест таго, каб перадаць спасылку на вектар, які, як правіла, лепш, таму што вяртае вектар, як вы робіце вымусіць копію. Напрыклад.: INT MySewer :: createCuttingArray (станд :: вектар і значэння, MyCloth ** тканіна, NxU32 StartPoint, NxU32 ENDPOINT)
дададзена аўтар Blazes, крыніца

7 адказы

«Правільны» спосаб справіцца з гэтым сапраўды залежыць ад таго, што фактычна робіць код атрымання вектара. Ці з'яўляецца гэта прычынай для памылкі, ці проста «мы будзем ігнараваць гэта»?

Калі гэта памылка, выкарыстоўвайце кінуць some_exception_goes_here , таму што гэта нашмат прасцей, чым па лініі са значэннем NULL.

Калі вы жадаеце проста ігнараваць яго, вяртае пусты вектар, а затым пераканайцеся, што ніжэй код не будзе мець праблемы з пустым вектарам.

11
дададзена

By your description, what you want is boost::optional>.

Я спадзяюся, што імя робіць яго намер відавочна.

http://www.boost.org/doc /libs/release/libs/optional/doc/html/index.html

7
дададзена
Мне гэта падабаецца, калі вы карыстаецеся імпульс ўжо так +1. Толькі будзьце асцярожныя, каб пісаць павышэнне :: апцыянальны <�станд :: вектар > (звярніце ўвагу на прабел памiж >>), калі ваш кампілятар не падтрымлівае >>.
дададзена аўтар Bathsheba, крыніца
Або станд :: опцыя у (спадзяюся) не занадта аддаленай будучыні.
дададзена аўтар juanchopanza, крыніца

Вы проста не можаце зрабіць гэта ў C ++.

Вы вяртаеце вектар, які будзе скапіяваны (і инстанцированный між іншым). Іншая справа ў тым, што вы не можаце кінуць нешта, што не з'яўляецца вектарам да NULL.

2
дададзена
@CaptainObvlious, а мы заўсёды вывучаючы новы матэрыял :). Тым не менш у стандарце C ++ вы проста не можаце вярнуць два тыпу.
дададзена аўтар André Moreira, крыніца
@CaptainObvlious Вы маеце рацыю, гэта быў абсалютны адказ :). Як вы адзначаеце, ёсць і іншыя спосабы, якія падтрымліваюцца стандартам;)
дададзена аўтар André Moreira, крыніца
-1. Вы не <�я> ведаю, , што гэта будзе <�я> скапіяваная . Копія можа быць не адзначаны ў працэсе аптымізацыі (РВО/NRVO) або плакат можа выкарыстоўваць C ++ 11 перамяшчэння семантыку з станд :: ходу() </а >
дададзена аўтар Captain Obvlious, крыніца
Калі я downvoted я быў капрызным, прабачце. Кропка I павінен зрабіў тое, што ваш адказ з'яўляецца занадта абсалютным, улічваючы, што ён не з'яўляецца дакладным. Яшчэ адным ключавым момантам з'яўляецца тое, што толькі таму, што сам мова не <�я> непасрэдна </я> Падтрымка нешта не значыць, што няма іншага шляху для яе выканання. Напрыклад, калі я хацеў вярнуцца <�я> два значэння я мог бы вярнуць зЬй :: пара <> замест гэтага. Гэта ўсё яшчэ тэхнічна які вяртае адно значэнне, але сама пара ўтрымлівае два значэння і будзе задавальняць патрабаванні неабходнага рашэння.
дададзена аўтар Captain Obvlious, крыніца
FWIW, калі вы атрымаеце яшчэ адзін downvote вы можаце выдаліць адказ і атрымаць знак ціску аднагодкаў;)
дададзена аўтар Captain Obvlious, крыніца

boost::optional addresses this problem by extending a type T to be a type that can either "have a value of type T" or "not have a value." In your case, you would be returning a boost::optional> because you want to, in some cases, return "nothing."

<�Код> бустер дакументацыя мае некаторыя прыклады .

This functionality seems basic enough that you might expect it to be part of the standard library. Sadly, it isn't (yet). See related: boost::optional alternative in C++ Standard Library

1
дададзена
<�Код> станд :: опцыя павінен быць часткай C ++ 14.
дададзена аўтар juanchopanza, крыніца

Я не думаю, што ёсць неабходнасць для любога падштурхоўвання :: опцыя , ні станд :: Exception . Тое, што вы павінны вярнуцца ў пусты вектар. Падумайце пра гэта. Функцыя вяртае спіс цэлых лікаў і функцыя выклікае абанент ў спісе цэлых лікаў. Калі спіс пусты, то няма нічога, каб аператар на. Так, напрыклад (у псевдопользователей)

std::vector data = createData(args);
for(int i = 0; i < data.size(); ++i){
      calculate(data[i]);
}

Гэта цыкл не будзе выконвацца, калі дадзеныя пусты. Там няма неабходнасці для нулявых праверак або апрацоўкі выключэнняў.

1
дададзена

У канчатковым рахунку, я думаю, я б змяніць карціну. Стварэнне вэктару ў выклікалым, перадаць у якасці спасылкі (або паказальніка) у вашу функцыю і мае які вяртаецца BOOL ісціна/хлусня, якія паказваюць на поспех або няўдачу.

Doing it this way also means you're not invoking the std::vector<> copy constructor on the return value.

Калі ў вас ужо ўсталяваны імпульс і запушчаны і працуе, я быў бы спакуса вярнуцца падштурхоўвання :: неабавязковы іншыя адказы паказваюць. Але зьвярніце ўвагу, што атрыманне імпульсу да працы можа быць галаўным болем, (яна мае сваю ўласную сераду распрацоўкі, якая з'яўляецца крывым навучання), асабліва, калі вы карыстаецеся STLPort.

0
дададзена
З цікавасці, што б вы зрабілі ў C ++ 11?
дададзена аўтар Bathsheba, крыніца
Калі памылка ігнаруемай, вяртае пусты вектар; Калі памылка не ігнаруемай, згенеруе выключэнне. Кліенцкі код будзе проста атрымаць вынік і апрацаваць яго (і выключэнні будуць апрацоўвацца ўсюды, дзе кліенцкі код апрацоўвае памылку).
дададзена аўтар utnapistim, крыніца
Гэта дрэнны інтэрфейс (хоць гэта быў добрым/пераважным выбарам, перш чым C ++ 11), таму што няма нічога прымушаючы кліенцкі код, каб праверыць вяртаецца значэнне (кліент можа лічыць вектар быў заселены) і таму што любая поўная рэалізацыя кліента будзе вымушана выкарыстоўваць, калі на вынік).
дададзена аўтар utnapistim, крыніца

Вы не можаце. Для таго, каб эмуляваць паводзіны спасылкавых тыпаў у .NET, з якіх зменныя могуць быць альбо прымацаванымі да рэальнага аб'екту або быць пустым, вам трэба выкарыстоўваць <�моцны> Паказальнікі у C ++. Паказальнікі могуць быць альбо NULL, альбо паказваць на сапраўдны аб'ект.

0
дададзена