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

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

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

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

Q&A

解決済

2回答

799閲覧

setのイテレーターがわからない。s.begin()と、for(auto &p:s)それぞれの違いを教えてほしい。

ratera

総合スコア54

C++

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

0グッド

1クリップ

投稿2020/08/23 22:18

前提・実現したいこと

setのイテレーターがわからない。

  • s.begin()
  • for(auto &p:s)文中でのp

それぞれの違いを教えてほしい。

※もし詳しい方がいらっしゃいましたら、typeidの戻り値の読み方について教えてください。
こちらのサイトを参考にしましたが、St23_Rb_tree_const_iteratorISt5tupleIJiiiEEESt5tupleIJiiiEEの網羅的な説明にはなりませんでした。
https://www.wdic.org/w/TECH/typeid

試したこと

  • s.begin()をtypeidで型を確認すると、St23_Rb_tree_const_iteratorISt5tupleIJiiiEEE
  • *s.begin()をtypeidで型を確認すると、St5tupleIJiiiEE
  • for(auto &p:s)文中でのpの型を確認すると、St5tupleIJiiiEE
  • for(auto &p:s)文中での*pの型を確認すると、コンパイルエラーになった

となった。

該当のソースコード

c++

1#include <bits/stdc++.h> 2#define rep(i, n) for (int i = 0; i < (n); ++i) 3#define rep1(i, n) for (int i = 1; i <= (n); ++i) 4using namespace std; 5using ll = long long; 6using P = pair<int, int>; 7using T = tuple<int, int, int>; 8 9int main() { 10 set<T> s;//重複を許さない順序付き集合 11 12 //要素自身がキーであり、重複を許さず、追加するたびにソートされることを確認 13 s.insert(T(4,2,5)); 14 s.emplace(3,3,3); 15 s.emplace(3,2,3); 16 s.emplace(1,2,1); 17 s.emplace(3,2,3);//要素が重複するので追加されない 18 19 //各値を出力させる.要素数+1の箇所が,s.end()のようだ 20 //auto itr=s.find(T(1,2)); 21 auto itr=s.begin(); 22 for(int i=0;i<=s.size();i++){ 23 cout << get<0>(*itr) << ","<< get<1>(*itr) << ","<< get<2>(*itr) << endl; 24 itr++; 25 } 26 cout << typeid(itr).name() << endl; 27 cout << typeid(*itr).name() << endl; 28 cout << endl; 29 for(auto &p:s){//&無くても動いた 30 cout << get<0>(p) << ","<< get<1>(p) << ","<< get<2>(p) << endl; 31 cout << typeid(p).name() << endl; 32 } 33 cout << endl; 34 //出力 //1,2 //3,2 //3,3 //4,2 //4,0 35 36 37 //count 指定したキーにマッチする要素の数を返す 38 cout << s.count(T(1,2,1))<<endl;//1 39 cout << s.count(T(10,3,4))<<endl;//0 40 cout << s.count(T(4,0,0))<<endl;//0 s.end()の要素は含まれない 41 cout << endl; 42 43 //find 指定したキーで要素を探す 44 auto itr1 = s.find(T(1,2,1)); 45 cout << get<0>(*itr1) << ","<< get<1>(*itr1) << ","<< get<2>(*itr1) << endl; 46 itr1 = s.find(T(20,3,4)); 47 cout << get<0>(*itr1) << ","<< get<1>(*itr1) << ","<< get<2>(*itr1) << endl; 48 //cout << *(s.find(T(10,3)))<<endl; 49 50 //contains 51 //if(s.contains(T(1,2))) cout << "contains" << endl; 52 cout << endl; 53 54 55 return 0; 56}

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

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

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

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

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

guest

回答2

0

ベストアンサー

範囲for文の仕様以下が詳しいですが

c++

1for(auto &p:s) {}

c++

1{ 2 auto && __range = s; 3 4 for (auto __begin = begin(__range), __end = end(__range); __begin != __end; ++__begin) 5 { 6 auto& p = *__begin; 7 } 8}

と等しいです。

つまり、p*s.begin()と同じです。


for(auto &p:s)for(auto p:s)の違い

auto &p = *begin(s)auto p = *begin(s)の違いです。
後者はコピーしますが前者はコピーしません。
配列でアドレスを比較すると分かりやすいかもしれません。

c++

1int main() { 2 int buff[4]; 3 cout << "for(auto i : buff)" << endl; 4 for(auto i : buff) cout << &i << endl; 5 cout << "for(auto &i : buff)" << endl; 6 for(auto &i : buff) cout << &i << endl; 7 cout << "for(size_t i = 0; i < size(buff); i++)" << endl; 8 for(size_t i = 0; i < size(buff); i++) cout << &buff[i] << endl; 9}

typeidについて

demangleすると人間が読めるようになるかもしれません。
gcc/clangの場合

c++

1#include <cxxabi.h> 2// 注意: freeしないとメモリリークします。 3char* demangle(const char *demangle) { 4 int status; 5 return abi::__cxa_demangle(demangle, 0, 0, &status); 6}

投稿2020/08/23 23:23

asm

総合スコア15149

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

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

0

s.begin() はイテレータ

for(auto &p:s)文中でのp はイテレータが指す値

両者の型は異なります。

投稿2020/08/23 23:17

episteme

総合スコア16612

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問