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

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

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

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

Q&A

解決済

1回答

1017閲覧

Setでイテレーターに対して*演算をした(*Set.lower_bound(x))ときになぜ要素が表示されるのかわからない

ratera

総合スコア54

C++

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

0グッド

0クリップ

投稿2020/07/07 10:50

質問事項

  1. Set.lower_bound(20)の返り値は、アドレスなのかイテレーター(配列の番号)のどちらでしょうか
  2. もし上記の回答が、イテレーターである場合、(*itr)で値を取り出せるのはSet特有のルールだからでしょうか

※補足:a[10]=5を例にすると、要素は「5」、アドレスは「&a+10」、イテレーターは「10」の認識です。
※補足2: 3-17.setを勉強中の質問です。こちらを見る限り、1の質問に対しては、イテレーターを返すという説明になっております。

事実と、私の期待値

添付のプログラムを実行し、cout << の出力時点では事実として以下の状況になりました。

イメージ説明

- itr2の値は46 : デバッガ参照 - (*itr2)の値は46 : 標準出力

これに対して、私の認識は以下の通りです。

- itr2の値は1のはず : {15,46}に対し、20以上のイテレーター(配列の番号)は1なので、`デバッガは嘘をついている`と判断 - Set.lower_boundの返り値はイテレーターを返す - 一方で、ただの`配列a[i]`へのlower_boundは、`アドレス`を返す(一貫性のないこともあるんでしょうか) - (*itr2)は、アドレス値が「1」の要素を返すので、変なことになりそう。

デバッガも嘘をつくようなことがあるのでしょうか...?

プログラム

C++

1#include <iostream> 2#include <set> 3using namespace std; 4 5int main() { 6 // 例 1: set に対して色々な操作を行う(1 個目は "End"、2 個目は "46" と出力される) 7 set<int> Set; 8 Set.insert(37); // その時点での Set の要素は {37} 9 Set.insert(15); // その時点での Set の要素は {15, 37} 10 Set.insert(37); // その時点での Set の要素は {15, 37} 11 Set.erase(37); // その時点での Set の要素は {15} 12 Set.insert(46); // その時点での Set の要素は {15, 46} 13 auto itr2 = Set.lower_bound(20); 14 cout << (*itr2) << endl; 15 16 return 0; 17}

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

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

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

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

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

SHOMI

2020/07/07 11:04 編集

>イテレーター(配列の番号) イテレータは要素番号ではありませんよ >イテレーター(配列の番号)は1なので、`デバッガは嘘をついている`と判断 なので、嘘なんてついていません。 VisualStudioのデバッガだとitr2が指す要素のアドレスも見れますよ。
ratera

2020/07/07 11:06 編集

ありがとうございます!そう考えるとスッキリしそうです ちなみにですが、イテレーターはアドレス値と同じ意味であっていますでしょうか? デバッガを見ると、アドレスの番号になっていない点が気になりました。 (auto itr2 = Set.lower_bound(20);でitr2の値は「46]になっている。)
SHOMI

2020/07/07 11:13 編集

内部的にはポインタで実装されているでしょうけれど、イテレータがポインタそのものである保証はありません。 ポインタのような別のものです。 vectorのような内部の要素がメモリ上で連続しているな構造ならポインタでもなんとかなりますが、setは連続していませんし…
SHOMI

2020/07/07 11:14

auto itr2 = Set.lower_bound(20); cout << typeid(itr2).name() << endl; として何者か表示するとポインタではないことがわかります。gccではデマングルが必要ですが。 class std::_Tree_const_iterator<class std::_Tree_val<struct std::_Tree_simple_types<int> > >
ratera

2020/07/07 11:26

ありがとうございます! イテレーターは自分の知っているものとは異なるものがあることに気づけました! イテレーター・デマングルについて、ちょっと実力が足りていないようなので、以下も含めて、いくつか調べてみようと思います! デマングル:https://gintenlabo.hatenablog.com/entry/20100116/1263681145
guest

回答1

0

ベストアンサー

イテレータにはメンバ関数: operator* が定義されているから。

C++

1#include <iostream> 2 3class iterator_poi_counter { 4 int count_; 5public: 6 iterator_poi_counter() : count_(0) {} 7 iterator_poi_counter& operator++() { ++count_; return *this; } 8 iterator_poi_counter& operator--() { --count_; return *this; } 9 int operator*() const { return count_; } // これな。 10}; 11 12int main() { 13 iterator_poi_counter ipc; 14 ++ipc; ++ipc; 15 std::cout << *ipc << std::endl; 16 return 0; 17}

投稿2020/07/07 12:55

編集2020/07/07 12:55
episteme

総合スコア16614

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

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

ratera

2020/07/07 14:25

いつもありがとうございます! (読むのに1時間もかかりましたが、読めてしまえば)わかりやすいですね! Set.hには見当たらなかったので、イテレータのメンバ関数の方なのですね
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問