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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

C++

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

Q&A

解決済

1回答

12127閲覧

std::mapへのポインタの格納方法についてご相談(map内の全要素が同じ値になってしまいます)

kotsukotsu

総合スコア12

C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

C++

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

0グッド

0クリップ

投稿2016/12/27 03:47

std::mapへのポインタの格納方法についてご相談です。
mapにポインタを格納したものの、
mapの全要素が同じ値になってしまいます。

お手数おかけしますが対処法をご教授いただけますと助かります。

C++

1Gamen::XYZ (const std::unordered_map<uint64_t, UserHoge>& refUnorderedMap) 2{ 3 // 引数で受け取ったstd::unordered_mapをstd::mapに詰め直す。 4 std::map<uint64_t, const UserHoge*> map; 5 for (const std::pair<uint64_t, UserHoge>& pair : refUnorderedMap) 6 { 7 // UserHogeはポインタで渡す 8 map.emplace(pair.first, &pair.second); 9 // 10 // この時点ではmapに正しく格納されている 11 // 12 } 13 14// 15// この時点で何ゆえかmapの全要素のUserHoge*が同じ値になっている。。。 16// 17 18 // std::mapをfor文で処理する 19 for (const std::pair<uint64_t, const UserHoge*>& pair : map) 20 { 21 // 何かしら処理 22 } 23}

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは。

不思議ですね。やってみました。確かにそのようになります。
原因は、unordered_map<>の要素の型違いです。
これのvalue_typeは、pair<const key_type,mapped_type>です。keyにconstがついてます。
しかし、for内で取り出す時のpairにつけていないため、一時オブジェクトが自動的に生成されてしまったのだと思います。(const参照は一時オブジェクトを受け取れますし。)

びっくりな頭の痛いミスですね。autoを使わなかったら私もハマると思います。
たぶん意図的にautoを使われていないのだと思いますが、autoを使った方が良いかも知れません。

c++

1#include <iostream> 2#include <unordered_map> 3#include <map> 4 5struct UserHoge 6{ 7 int mNum; 8 UserHoge(int iNum) : mNum(iNum) { } 9}; 10 11void foo(const std::unordered_map<uint64_t, UserHoge>& refUnorderedMap) 12{ 13 // 引数で受け取ったstd::unordered_mapをstd::mapに詰め直す。 14 std::map<uint64_t, const UserHoge*> map; 15// for (const std::pair<uint64_t, UserHoge>& pair : refUnorderedMap) 16 for (auto&& pair : refUnorderedMap) 17 { 18 // UserHogeはポインタで渡す 19 map.emplace(pair.first, &pair.second); 20 // 21 // この時点ではmapに正しく格納されている 22 // 23 std::cout << "---- &pair.second=" << &pair.second << "\n"; 24 for (const std::pair<uint64_t, const UserHoge*>& pair : map) 25 { 26 // 何かしら処理 27 std::cout << "[" << pair.first << "] " 28 << pair.second->mNum << " " << pair.second << "\n"; 29 } 30 } 31 std::cout << "==========================\n"; 32 33// 34// この時点で何ゆえかmapの全要素のUserHoge*が同じ値になっている。。。 35// 36 37 // std::mapをfor文で処理する 38 for (const std::pair<uint64_t, const UserHoge*>& pair : map) 39 { 40 // 何かしら処理 41 std::cout << "[" << pair.first << "] " 42 << pair.second->mNum << " " << pair.second << "\n"; 43 } 44} 45 46int main() 47{ 48 std::unordered_map<uint64_t, UserHoge> UnorderedMap; 49 50 UnorderedMap.emplace(1, UserHoge(100)); 51 UnorderedMap.emplace(2, UserHoge(200)); 52 UnorderedMap.emplace(3, UserHoge(300)); 53 54 for (auto&& pair : UnorderedMap) 55 { 56 // 何かしら処理 57 std::cout << "[" << pair.first << "] " 58 << pair.second.mNum << " " << &pair.second << "\n"; 59 } 60 61 foo(UnorderedMap); 62 63 return 0; 64}

投稿2016/12/27 04:55

編集2016/12/27 04:59
Chironian

総合スコア23272

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

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

kotsukotsu

2016/12/27 06:23

ありがとうございます。autoにして解決いたしました。 m(_ _)m (autoを使っていなかった理由は、autoを使わない方が  コードが読みやすいと思っていたためでした。。。  今後は気をつけたいと思います。。。)
episteme

2016/12/27 06:40

autoが嫌なら map<K,V>::value_type ではどうだろう。
Chironian

2016/12/27 06:59

> autoを使わない方がコードが読みやすいと思っていたため これはありと思います。書く時はauto使うと楽なんですけど読む時やデバッグの時は頭痛いです。 epistemeさん提案の方法は読む人に優しいと思いますよ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問