質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Null

Nullとは、プログラミング言語やデータベースにおけるデータ表現の一種です。コンテキストによって"空"もしくは"長さ0の文字列"、”未知・不明”を意味します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

1759閲覧

weak_ptrを返り値にした時nullだった時の対処法

suittizihou

総合スコア27

Null

Nullとは、プログラミング言語やデータベースにおけるデータ表現の一種です。コンテキストによって"空"もしくは"長さ0の文字列"、”未知・不明”を意味します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/05/21 15:25

編集2019/05/22 01:29

テンプレートで型を指定してdynamic_pointer_castを使ってキャストした後でweak_ptr変数に格納して返すという処理を作っているのですが、探したいオブジェクトが見つからなかった時にnullptrで返せないので行き詰っています、、、。
weak_ptrの場合どのようにすれば何もないという命令になるのでしょうか?
返り値がweak_ptr<T>なのでtrue / falseで返せなくてかなり困っています、、、。

C++

1 // コンポーネントの参照を取得 2 template<typename T> 3 inline std::weak_ptr<T> GetComponent() { 4 std::weak_ptr<T> component_tmp; 5 // コンポーネントを検索 6 for (std::shared_ptr<Component> component : components) { 7 // Component型で登録されているコンポーネントを指定された型にダウンキャスト 8 component_tmp = std::dynamic_pointer_cast<T>(component); 9 // あったら返す 10 if (!component_tmp.expired()) { 11 return component_tmp; 12 } 13 } 14 return ???; 15 }

補足
すみません質問文の最後にboolで返すような記述をしてしまい誤解が生まれてしまったかもしれません。
返り値はweak_ptrのままで戻り値はboolにはしないつもりです。
やりたいことはweak_ptrがnullの時、例えば受け取り側で

C++

1std::weak_ptr<Rigidbody> p_rigid; 2p_rigid = GetComponent<Rigidbody>();

とした際コンポーネントリストにRigidbodyが存在しない場合

C++

1p_rigid = GetComponent<Rigidbody>();

の時点でエラーが出て止まってほしいんです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

デフォルト・コンストラクトされたやつは監視対象を持たないので、
そのまま component_temp を返せばよくね?

投稿2019/05/21 19:33

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

suittizihou

2019/05/23 07:25

遅れてしまいすみません。 ありがとうございます。
guest

0

オブジェクト寿命が切れていた時に例外を投げることで止まるようにしました。
すみません考えればかなり単純でした、、、

C++

1 // コンポーネントのポインターを取得 2 template<typename T> 3 inline std::weak_ptr<T> GetComponent() { 4 std::weak_ptr<T> component_tmp; 5 // コンポーネントを検索 6 for (std::shared_ptr<Component> component : components) { 7 // Component型で登録されているコンポーネントを指定された型にダウンキャスト 8 component_tmp = std::dynamic_pointer_cast<T>(component); 9 // あったら返す 10 if (!component_tmp.expired()) { 11 return component_tmp.lock(); 12 } 13 } 14 // 追加 15         throw std::range_error("Not Component"); 16 return component_tmp; 17 } 18

投稿2019/05/22 01:55

編集2019/05/22 02:18
suittizihou

総合スコア27

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

こんにちは。

if (component_tmp.expired())if ( ! component_tmp.expired())の間違いのような気がしますが、もし間違いでないなら戻り値はshared_ptr<T>(nullptr)のweak_ptrですから意味がないので、戻り値をboolにしてもよいように感じます。

if ( ! component_tmp.expired())の間違いでしたら、戻り値をlockすると「T型へダイナミックキャストした先を保持するshared_ptr<<T>」が返ってくる筈なので意味があると思います。

この場合、「見つからなかった」時は「監視対象のない」weak_ptrをreturnする方法が使えるかもしれません。(ごめんなさい。未定義動作のリスクが結構高いです。でも、監視対象の有無判定の需要は有る筈なのでちょっと期待しています。)

cpprefjp - C++日本語リファレンスをたどって、std::shared_ptr<T>::owner_beforeの解説を見ると以下のように書かれています。

技術的には、shared_ptrが内部でメモリ確保している、参照カウンタオブジェクトのポインタ比較を行う。

この解説に頼り、かつ監視対象がない時にそのポインタがnullptrであれば次のような関数にて、監視対象の有無を判定できる筈です。

C++

1template<typename T> 2bool isEmpty(std::weak_ptr<T> const& w) 3{ 4 std::weak_ptr<T> z; 5 return !z.owner_before(w) && !w.owner_before(z); 6}

投稿2019/05/21 19:42

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2019/05/21 19:47

w.lock().get() が nullptr ならからっぽなんじゃないすか?
Chironian

2019/05/21 19:56

あああ、その通りですね。 if (component_tmp.expired())が正しい場合は、expired()なものがどちらのケースでも返却されるので判別できるかな?って考えた結果を書いてしまってました。 これが正しい時は bool で十分なので意味なかったです。
suittizihou

2019/05/22 01:31

すみませんコードが間違っていたので修正しました if(component_tmp.expired())ではなく if(!component_tmp_expired())でした。(コメント通りまだ存在している時に返すため)
Chironian

2019/05/22 03:29

であれば、epistemeさんの回答内容でOKと思いますよ。
suittizihou

2019/05/23 07:26

ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問