|
|
(35 intermediate revisions by 6 users not shown) |
Line 1: |
Line 1: |
− | {{#switch:{{{1|}}}|span={{cpp/container/{{{1|}}}/title | begin }} | + | {{#vardefine:cont|{{{1|inplace_vector}}}}}<!-- |
− | |#default={{cpp/container/{{{1|}}}/title | begin | cbegin}}
| + | -->{{cpp/container/{{#var:cont}}/title|begin|cbegin}} |
− | }} | + | {{cpp/container/{{#var:cont}}/navbar}} |
− | {{cpp/container/{{{1|}}}/navbar}} | + | |
− | {{#switch:{{{1|}}}|array=
| + | |
| {{dcl begin}} | | {{dcl begin}} |
− | {{dcl rev begin}} | + | {{#switch:{{#var:cont}} |
− | {{dcl | until=c++17| | + | |array= |
| + | {{dcl|num=1|since=c++11|notes={{mark constexpr since c++17}}| |
| iterator begin() noexcept; | | iterator begin() noexcept; |
| }} | | }} |
− | {{dcl | since=c++17| | + | {{dcl|num=2|since=c++11|notes={{mark constexpr since c++17}}| |
− | constexpr iterator begin() noexcept;
| + | |
− | }}
| + | |
− | {{dcl rev end}} | + | |
− | {{dcl rev begin}}
| + | |
− | {{dcl | until=c++17|
| + | |
| const_iterator begin() const noexcept; | | const_iterator begin() const noexcept; |
| }} | | }} |
− | {{dcl | since=c++17| | + | {{dcl|num=3|since=c++11|notes={{mark constexpr since c++17}}| |
− | constexpr const_iterator begin() const noexcept;
| + | const_iterator cbegin() const noexcept; |
| }} | | }} |
− | {{dcl rev end}} | + | |vector= |
− | {{dcl rev begin}} | + | {{dcl|num=1|notes={{mark noexcept since c++11}}<br>{{mark constexpr since c++20}}| |
− | {{dcl | until=c++17| | + | iterator begin(); |
| + | }} |
| + | {{dcl|num=2|notes={{mark noexcept since c++11}}<br>{{mark constexpr since c++20}}| |
| + | const_iterator begin() const; |
| + | }} |
| + | {{dcl|num=3|since=c++11|notes={{mark constexpr since c++20}}| |
| const_iterator cbegin() const noexcept; | | const_iterator cbegin() const noexcept; |
| }} | | }} |
− | {{dcl | since=c++17| | + | |inplace_vector= |
| + | {{dcl|num=1|since=c++26| |
| + | constexpr iterator begin() noexcept; |
| + | }} |
| + | {{dcl|num=2|since=c++26| |
| + | constexpr const_iterator begin() const noexcept; |
| + | }} |
| + | {{dcl|num=3|since=c++26| |
| constexpr const_iterator cbegin() const noexcept; | | constexpr const_iterator cbegin() const noexcept; |
| }} | | }} |
− | {{dcl rev end}}
| |
− | {{dcl end}}
| |
| |span= | | |span= |
− | {{dcl begin}}
| + | {{dcl|num=1|since=c++20| |
− | {{dcl |1= | + | |
| constexpr iterator begin() const noexcept; | | constexpr iterator begin() const noexcept; |
| }} | | }} |
− | {{dcl end}} | + | {{dcl|num=2|since=c++23| |
− | |{{dcl begin}} | + | constexpr const_iterator cbegin() const noexcept; |
− | {{cpp/container/noexcept dcl | {{{1|}}}|dcl= | + | }} |
| + | |flat_map|flat_multimap|flat_set|flat_multiset= |
| + | {{dcl|num=1|since=c++23| |
| + | iterator begin() noexcept; |
| + | }} |
| + | {{dcl|num=2|since=c++23| |
| + | const_iterator begin() const noexcept; |
| + | }} |
| + | {{dcl|num=3|since=c++23| |
| + | const_iterator cbegin() const noexcept; |
| + | }} |
| + | | |
| + | {{cpp/container/noexcept dcl|num=1|{{#var:cont}}|dcl= |
| iterator begin() | | iterator begin() |
| }} | | }} |
− | {{cpp/container/noexcept dcl | {{{1|}}}|dcl= | + | {{cpp/container/noexcept dcl|num=2|{{#var:cont}}|dcl= |
| const_iterator begin() const | | const_iterator begin() const |
| }} | | }} |
− | {{dcl | since={{cpp/std|{{{1|}}}|c++11}} | | + | {{dcl|num=3|since={{cpp/std|{{#var:cont}}|c++11}}| |
| const_iterator cbegin() const noexcept; | | const_iterator cbegin() const noexcept; |
| }} | | }} |
− | {{dcl end}}}} | + | }} |
| + | {{dcl end}} |
| | | |
− | Returns an iterator to the first element of the {{tt|{{{1}}}}}. | + | Returns an iterator to the first element of the {{tt|{{#var:cont}}}}. |
| | | |
− | If the {{tt|{{{1}}}}} is empty, the returned iterator will be equal to {{lc|end()}}. | + | If the {{tt|{{#var:cont}}}} is empty, the returned iterator will be equal to {{lc|end()}}. |
| | | |
| {{image|range-begin-end.svg}} | | {{image|range-begin-end.svg}} |
Line 62: |
Line 78: |
| ===Complexity=== | | ===Complexity=== |
| Constant. | | Constant. |
− | {{#if:{{#pos:{{{1}}}|set}}|{{cpp/container/constant iterator note}}}} | + | <!----> |
− | | + | {{#ifexpr:{{cpp/container/if c++98|{{#var:cont}}|1|0}}or{{cpp/container/if set|{{#var:cont}}|1|0}}| |
| + | ===Notes=== |
| + | {{cpp/container/if set|{{#var:cont}}|{{cpp/container/constant iterator note}}}} |
| + | {{cpp/container/if c++98|{{#var:cont}}|<p>libc++ backports {{tt|cbegin()}} to C++98 mode.</p>}}}} |
| + | <!----> |
| ===Example=== | | ===Example=== |
− | {{#switch:{{{1|}}}|unordered_multiset= | + | {{#switch:{{#var:cont}} |
− | {{example|code=
| + | |deque|forward_list|list|vector={{cpp/container/begin/examples/sequence|{{#var:cont}}}} |
− | #include <iostream> | + | |{{cpp/container/begin/examples/{{#var:cont}}}} |
− | #include <iterator>
| + | |
− | #include <string>
| + | |
− | #include <unordered_set>
| + | |
− | | + | |
− | int main() {
| + | |
− | const std::unordered_multiset<std::string> words = {
| + | |
− | "some", "words", "to", "count",
| + | |
− | "count", "these", "words"
| + | |
− | };
| + | |
− | | + | |
− | for (auto it = words.begin(); it != words.end(); ) {
| + | |
− | auto cnt = words.count(*it);
| + | |
− | std::cout << *it << ":\t" << cnt << '\n';
| + | |
− | std::advance(it, cnt); // all cnt elements have equivalent keys
| + | |
− | }
| + | |
− | } | + | |
− | |p=true | + | |
− | |std=c++11 | + | |
− | |output= | + | |
− | some: 1
| + | |
− | words: 2
| + | |
− | to: 1
| + | |
− | count: 2
| + | |
− | these: 1
| + | |
− | }}
| + | |
− | |multiset= | + | |
− | {{example|code= | + | |
− | #include <iostream>
| + | |
− | #include <iterator>
| + | |
− | #include <set>
| + | |
− | #include <string>
| + | |
− | | + | |
− | int main()
| + | |
− | {
| + | |
− | const std::multiset<std::string> words = {
| + | |
− | "some", "not", "sorted", "words",
| + | |
− | "will", "come", "out", "sorted",
| + | |
− | };
| + | |
− | | + | |
− | for (auto it = words.begin(); it != words.end(); ) {
| + | |
− | auto cnt = words.count(*it);
| + | |
− | std::cout << *it << ":\t" << cnt << '\n';
| + | |
− | std::advance(it, cnt); // all cnt elements have equivalent keys
| + | |
− | }
| + | |
− | }
| + | |
− | |p=true
| + | |
− | |std=c++11
| + | |
− | |output=
| + | |
− | come: 1
| + | |
− | not: 1
| + | |
− | out: 1
| + | |
− | some: 1
| + | |
− | sorted: 2
| + | |
− | will: 1
| + | |
− | words: 1
| + | |
− | }}
| + | |
− | |map=
| + | |
− | {{example|code=
| + | |
− | #include <iostream>
| + | |
− | #include <map>
| + | |
− |
| + | |
− | int main() {
| + | |
− | std::map<int, float> num_map;
| + | |
− | num_map[4] = 4.13;
| + | |
− | num_map[9] = 9.24;
| + | |
− | num_map[1] = 1.09;
| + | |
− | // calls a_map.begin() and a_map.end()
| + | |
− | for (auto it = num_map.begin(); it != num_map.end(); ++it) {
| + | |
− | std::cout << it->first << ", " << it->second << '\n';
| + | |
− | }
| + | |
− | }
| + | |
− | | output=
| + | |
− | 1, 1.09
| + | |
− | 4, 4.13
| + | |
− | 9, 9.24
| + | |
− | }}
| + | |
− | ====Example using a custom comparison function====
| + | |
− | {{example|code=
| + | |
− | #include <cmath>
| + | |
− | #include <iostream>
| + | |
− | #include <map>
| + | |
− |
| + | |
− | struct Point { double x, y; };
| + | |
− | | + | |
− | typedef Point * PointPtr;
| + | |
− | //Compare the x-coordinates of two Point pointers | + | |
− | struct PointCmp {
| + | |
− | bool operator()(const PointPtr &lhs, const PointPtr &rhs) const {
| + | |
− | return lhs->x < rhs->x;
| + | |
− | }
| + | |
− | };
| + | |
− |
| + | |
− | int main() {
| + | |
− | //Note that although the x-coordinates are out of order, the
| + | |
− | // map will be iterated through by increasing x-coordinates
| + | |
− | Point points[3] = { {2, 0}, {1, 0}, {3, 0} };
| + | |
− | | + | |
− | //mag is a map sending the address of node to its magnitude in the x-y plane
| + | |
− | //Although the keys are pointers-to-Point, we want to order the map by the
| + | |
− | // x-coordinates of the points and NOT by the addresses of the Points. This
| + | |
− | // is done by using the PointCmp class's comparison method.
| + | |
− | std::map<Point *, double, PointCmp> mag({
| + | |
− | { points, 2 },
| + | |
− | { points + 1, 1 },
| + | |
− | { points + 2, 3 }
| + | |
− | });
| + | |
− | | + | |
− | //Change each y-coordinate from 0 to the magnitude
| + | |
− | for(auto iter = mag.begin(); iter != mag.end(); ++iter){
| + | |
− | auto cur = iter->first; // pointer to Node
| + | |
− | cur->y = mag[cur]; // could also have used cur->y = iter->second;
| + | |
− | }
| + | |
− |
| + | |
− | //Update and print the magnitude of each node
| + | |
− | for(auto iter = mag.begin(); iter != mag.end(); ++iter){
| + | |
− | auto cur = iter->first;
| + | |
− | mag[cur] = std::hypot(cur->x, cur->y);
| + | |
− | std::cout << "The magnitude of (" << cur->x << ", " << cur->y << ") is ";
| + | |
− | std::cout << iter->second << '\n';
| + | |
− | }
| + | |
− |
| + | |
− | //Repeat the above with the range-based for loop
| + | |
− | for(auto i : mag) {
| + | |
− | auto cur = i.first;
| + | |
− | cur->y = i.second;
| + | |
− | mag[cur] = std::hypot(cur->x, cur->y);
| + | |
− | std::cout << "The magnitude of (" << cur->x << ", " << cur->y << ") is ";
| + | |
− | std::cout << mag[cur] << '\n';
| + | |
− | //Note that in contrast to std::cout << iter->second << '\n'; above,
| + | |
− | // std::cout << i.second << '\n'; will NOT print the updated magnitude
| + | |
− | }
| + | |
− | }
| + | |
− | | output= | + | |
− | The magnitude of (1, 1) is 1.41421
| + | |
− | The magnitude of (2, 2) is 2.82843
| + | |
− | The magnitude of (3, 3) is 4.24264
| + | |
− | The magnitude of (1, 1.41421) is 1.73205
| + | |
− | The magnitude of (2, 2.82843) is 3.4641
| + | |
− | The magnitude of (3, 4.24264) is 5.19615
| + | |
− | }}
| + | |
− | |set=
| + | |
− | {{example|code= | + | |
− | #include <set> | + | |
− | #include <iostream>
| + | |
− |
| + | |
− | int main() {
| + | |
− | std::set<int> set = { 6, 1, 3, 4, 2, 5 };
| + | |
− | for (auto it = set.begin(); it != set.end(); ++it)
| + | |
− | std::cout << *it << "\n";
| + | |
− | } | + | |
− | |p=true
| + | |
− | |std=c++11
| + | |
− | |output=
| + | |
− | 1
| + | |
− | 2
| + | |
− | 3
| + | |
− | 4
| + | |
− | 5
| + | |
− | 6
| + | |
− | }} | + | |
− | |unordered_map= | + | |
− | {{example|code= | + | |
− | #include <cmath>
| + | |
− | #include <iostream>
| + | |
− | #include <unordered_map>
| + | |
− | | + | |
− | struct Node { double x, y; };
| + | |
− | | + | |
− | int main() {
| + | |
− | Node nodes[3] = { {1, 0}, {2, 0}, {3, 0} };
| + | |
− |
| + | |
− | //mag is a map mapping the address of a Node to its magnitude in the plane
| + | |
− | std::unordered_map<Node *, double> mag = {
| + | |
− | { nodes, 1 },
| + | |
− | { nodes + 1, 2 },
| + | |
− | { nodes + 2, 3 }
| + | |
− | };
| + | |
− |
| + | |
− | //Change each y-coordinate from 0 to the magnitude
| + | |
− | for(auto iter = mag.begin(); iter != mag.end(); ++iter){
| + | |
− | auto cur = iter->first; // pointer to Node
| + | |
− | cur->y = mag[cur]; // could also have used cur->y = iter->second;
| + | |
− | }
| + | |
− |
| + | |
− | //Update and print the magnitude of each node
| + | |
− | for(auto iter = mag.begin(); iter != mag.end(); ++iter){
| + | |
− | auto cur = iter->first;
| + | |
− | mag[cur] = std::hypot(cur->x, cur->y);
| + | |
− | std::cout << "The magnitude of (" << cur->x << ", " << cur->y << ") is ";
| + | |
− | std::cout << iter->second << '\n';
| + | |
− | }
| + | |
− | | + | |
− | //Repeat the above with the range-based for loop
| + | |
− | for(auto i : mag) {
| + | |
− | auto cur = i.first;
| + | |
− | cur->y = i.second;
| + | |
− | mag[cur] = std::hypot(cur->x, cur->y);
| + | |
− | std::cout << "The magnitude of (" << cur->x << ", " << cur->y << ") is ";
| + | |
− | std::cout << mag[cur] << '\n';
| + | |
− | //Note that in contrast to std::cout << iter->second << '\n'; above,
| + | |
− | // std::cout << i.second << '\n'; will NOT print the updated magnitude
| + | |
− | }
| + | |
− | }
| + | |
− | |p=true
| + | |
− | |std=c++11
| + | |
− | |output=
| + | |
− | The magnitude of (3, 3) is 4.24264
| + | |
− | The magnitude of (1, 1) is 1.41421
| + | |
− | The magnitude of (2, 2) is 2.82843
| + | |
− | The magnitude of (3, 4.24264) is 5.19615
| + | |
− | The magnitude of (1, 1.41421) is 1.73205
| + | |
− | The magnitude of (2, 2.82843) is 3.4641
| + | |
− | | + | |
− | }}
| + | |
− | |unordered_set=
| + | |
− | {{example|code=
| + | |
− | #include <iostream> | + | |
− | #include <unordered_set>
| + | |
− | | + | |
− | struct Point { double x, y; };
| + | |
− | | + | |
− | int main() {
| + | |
− | Point pts[3] = { {1, 0}, {2, 0}, {3, 0} };
| + | |
− |
| + | |
− | //points is a set containing the addresses of points
| + | |
− | std::unordered_set<Point *> points = { pts, pts + 1, pts + 2 };
| + | |
− |
| + | |
− | //Change each y-coordinate of (i, 0) from 0 into i^2 and print the point
| + | |
− | for(auto iter = points.begin(); iter != points.end(); ++iter){
| + | |
− | (*iter)->y = ((*iter)->x) * ((*iter)->x); //iter is a pointer-to-Point*
| + | |
− | std::cout << "(" << (*iter)->x << ", " << (*iter)->y << ") ";
| + | |
− | }
| + | |
− | std::cout << '\n';
| + | |
− |
| + | |
− | //Now using the range-based for loop, we increase each y-coordinate by 10
| + | |
− | for(Point * i : points) {
| + | |
− | i->y += 10;
| + | |
− | std::cout << "(" << i->x << ", " << i->y << ") ";
| + | |
− | }
| + | |
− | }
| + | |
− | |p=true
| + | |
− | |std=c++11
| + | |
− | |output=
| + | |
− | (3, 9) (1, 1) (2, 4)
| + | |
− | (3, 19) (1, 11) (2, 14)
| + | |
− | }}
| + | |
− | |vector|list|forward_list|deque=
| + | |
− | {{example|code=
| + | |
− | #include <iostream>
| + | |
− | #include <{{{1}}}>
| + | |
− | #include <string>
| + | |
− | | + | |
− | int main()
| + | |
− | {
| + | |
− | std::{{{1}}}<int> ints {1, 2, 4, 8, 16};
| + | |
− | std::{{{1}}}<std::string> fruits {"orange", "apple", "raspberry"};
| + | |
− | std::{{{1}}}<char> empty;
| + | |
− | | + | |
− | // Sums all integers in the {{{1}}} ints (if any), printing only the result.
| + | |
− | int sum = 0;
| + | |
− | for (auto it = ints.cbegin(); it != ints.cend(); it++)
| + | |
− | sum += *it;
| + | |
− | std::cout << "Sum of ints: " << sum << "\n";
| + | |
− | | + | |
− | // Prints the first fruit in the {{{1}}} fruits, without checking if there is one.
| + | |
− | std::cout << "First fruit: " << *fruits.begin() << "\n";
| + | |
− | | + | |
− | if (empty.begin() == empty.end())
| + | |
− | std::cout << "{{{1}}} 'empty' is indeed empty.\n";
| + | |
− | }
| + | |
− | |output=
| + | |
− | Sum of ints: 31
| + | |
− | First fruit: orange
| + | |
− | {{{1}}} 'empty' is indeed empty.
| + | |
− | }}
| + | |
− | |array=
| + | |
− | {{example
| + | |
− | |code=
| + | |
− | #include <array>
| + | |
− | #include <iostream>
| + | |
− | #include <algorithm>
| + | |
− | #include <iomanip>
| + | |
− | | + | |
− | int main()
| + | |
− | {
| + | |
− | std::cout << std::boolalpha;
| + | |
− | | + | |
− | std::array<int, 0> empty;
| + | |
− | std::cout << "1) "
| + | |
− | << (empty.begin() == empty.end()) << ' ' // true
| + | |
− | << (empty.cbegin() == empty.cend()) << '\n'; // true
| + | |
− | // *(empty.begin()) = 42; // => undefined behaviour at run-time
| + | |
− | | + | |
− | | + | |
− | std::array<int, 4> numbers{5, 2, 3, 4};
| + | |
− | std::cout << "2) "
| + | |
− | << (numbers.begin() == numbers.end()) << ' ' // false
| + | |
− | << (numbers.cbegin() == numbers.cend()) << '\n' // false
| + | |
− | << "3) "
| + | |
− | << *(numbers.begin()) << ' ' // 5
| + | |
− | << *(numbers.cbegin()) << '\n'; // 5
| + | |
− | | + | |
− | *numbers.begin() = 1;
| + | |
− | std::cout << "4) " << *(numbers.begin()) << '\n'; // 1
| + | |
− | // *(numbers.cbegin()) = 42; // compile-time error:
| + | |
− | // read-only variable is not assignable
| + | |
− | | + | |
− | // print out all elements
| + | |
− | std::cout << "5) ";
| + | |
− | std::for_each(numbers.cbegin(), numbers.cend(), [](int x) {
| + | |
− | std::cout << x << ' ';
| + | |
− | });
| + | |
− | std::cout << '\n';
| + | |
− | | + | |
− | | + | |
− | constexpr std::array constants{'A', 'B', 'C'};
| + | |
− | static_assert(constants.begin() != constants.end()); // OK
| + | |
− | static_assert(constants.cbegin() != constants.cend()); // OK
| + | |
− | static_assert(*constants.begin() == 'A'); // OK
| + | |
− | static_assert(*constants.cbegin() == 'A'); // OK
| + | |
− | // *constants.begin() = 'Z'; // compile-time error:
| + | |
− | // read-only variable is not assignable
| + | |
− | }
| + | |
− | |output=
| + | |
− | 1) true true
| + | |
− | 2) false false
| + | |
− | 3) 5 5
| + | |
− | 4) 1
| + | |
− | 5) 1 2 3 4
| + | |
− | }}
| + | |
− | |{{example}}
| + | |
| }} | | }} |
| | | |
| ===See also=== | | ===See also=== |
− |
| |
| {{dsc begin}} | | {{dsc begin}} |
− | {{dsc inc | cpp/container/dsc end |{{{1|}}}}} | + | {{dsc inc|cpp/container/dsc end|{{#var:cont}}}} |
| + | {{dsc inc|cpp/iterator/dsc begin}} |
| {{dsc end}} | | {{dsc end}} |
Iterator to the first element.
Constant.