2016-03-28 16 views
0

関数の戻り値の型がstd::string&で、関数内で条件が一致しない場合NULLを返すにはどうすればいいですか?string&C++関数はNULL文字列リファレンスを返します

std::string& SomeClass::getSomething() 
{ 
    if(){...} 
    else if(){...} 
    // return a NULL 
} 
+9

できません。 NULLの 'std :: string'のようなものはありません。あなたはあなたのアプローチを再考する必要があります。 – juanchopanza

+0

おそらく空の文字列を返しますか? – DimChtz

+0

参照の代わりにポインタを返すことができます。その後、NULLポインタを返すことができます。 – Unimportant

答えて

5

C++の参照がnullにすることはできません。

データメンバのように、関数呼び出しのスコープに関連付けられていないオブジェクトへの参照を返す場合は、生ポインタを安全に返すことができます。ポインタをにすることをお勧めします。

std::string const* foo::bar() const { 
    if (condition) { 
     return &some_data_member; 
    } else { 
     return nullptr; 
    } 
} 

ない場合は、最善の解決策は、boost::optional(またはC++ 17でstd::optional)のようなラッパー型を使用することです。これにより、オプションのオブジェクトを値で返すことができます(これはパフォーマンスが向上する可能性があります)。self-documentingです。

std::optional<std::string> foo::bar() const { 
    if (condition) { 
     return "hello, world"; 
    } else { 
     return std::nullopt; 
    } 
} 

また、ポインタを返すこともできますが、nullでもかまいません。しかし、生ポインタを返すことで、動的に割り当てられた文字列を誰が削除するのかが問われます。この場合、所有者が呼び出し側に明示的に渡されるため、std::unique_ptrを返すことが最適なオプションになります。

std::unique_ptr<std::string> foo::bar() const { 
    if (condition) { 
     return std::make_unique<std::string>("hello, world"); 
    } else { 
     return nullptr; 
    } 
} 

さらに単純なケースでは、空の文字列を返すこともできます。そして正直なところ、これは私の好みのアプローチです(KISS)。

std::string foo::bar() const { 
    if (condition) { 
     return "hello, world"; 
    } else { 
     return ""; 
    } 
} 
+0

元のコードでは、リターンする人が参照されている文字列を所有しているので、所有していない生ポインタを返すのはいいと思います。 unique_ptrを返すことで、呼び出し側に所有権が移ります。これは、セマンティクスWRTの深刻な変更です。元のコード – juanchopanza

+0

@juanchopanza注目。 –

0

juanchopanzaによってコメントで述べたように、あなたがすることはできません。

NULLをテストする必要がある場合は、スマートポインタを使用してアプローチを再考することができます。例えばstd::shared_ptr<std::string>

std::shared_ptr<std::string> SomeClass::getSomething() 
{ 
    std::shared_ptr<std::string> stringPtr; 
    if(){ 
     //... 
     stringPtr = std::make_shared<std::string>("Whatever string goes here"); 
    } 
    else if(){ 
     //... 
     stringPtr = std::make_shared<std::string>("The other string..."); 
    } 
    return stringPtr; 
} 

次に、あなただけのブール値への暗黙的な変換とstd::shared_ptrをテストすることができます:

auto strReturnedPtr = someClassObj.getSomething(); 
if (strReturnedPtr) 
{ 
    // Do stuff 
} 
+0

新しい、しかし 'stringPtr = make_shared ... 'を使用しないでください –

+0

なぜshared_ptr?この中の唯一の参加者は発信者とgetSomethingのようであり、getSometingは発信者に引き継がれたゲームから外れています。 @DieterLückingは言及しました: – user4581301

+0

前にそれを修正することができませんでした、私は奇妙なので、 "Ooops何かが間違っていた"を得ていた。 – Nacho

1

とにかくあなたはNULLが、nullptrを返しません。 また、関数からの参照を返すことに注意し、参照が有効な生存オブジェクトを参照することを確認する必要があります。ローカルオブジェクトへの参照を返すことが間違っています。

nullptrnullptrはポインタであり、string&は参考資料であるため、返品することはできません。

あなたのオプションは次のとおりです。

  1. は、オプションのクラス(boost::optional、などのようなものを使用して例外
  2. を投げます私は、関数が失敗する可能性が強い可能性がある知っていれば)

個人的に、私は参照型の引数に結果を渡すと失敗

bool SomeClass::getSomething(std::string& result) 
{ 
    if(){result = "success 1"; return true; } 
    else if(){result = "success 2"; return true; } 
    return false. 
} 
+1

1970年代は...と呼ばれる! –

+0

@BarryTheHatchetので、.Netはあなたに 'TryParse'、' TryGetValue'を与えます。それは涼しくてモダンですが、C++では突然古くて醜いのですか? –

+1

「TryParse」と「TryGetValue」は「クールでモダン」なのはいつですか? (ヒント:私はしなかった)(もう一つのヒント:それらは古くて醜​​い、あまりにも) –

0

空を返すの成功を示すためにboolを返します文字列 ''はここで意味をなさないかもしれません。

あなたのコードの断片からは、クラスのカバーの下を見て、クラスそのものが作成しなければならないという決定を下すかどうか疑問に思うでしょう。 Martin Fowlerの記事「Tell, don't Ask」も参照してください。これは、The Pragmatic Programmersのオリジナル記事を参照してください。

関連する問題