Używam XCode, Yosemite.pusty nawias klamrowy {} jako koniec zakresu
Poniższy kod został skompilowany, ale zawiesza się w czasie wykonywania, dlaczego?
Celowo użyłem "{}" w drugim std :: copy jako "koniec zakresu".
Eksperymentowałem z tym kodem z powodu działającego przykładu, który użył "{}" jako "domyślnie skonstruowanego iteratora strumienia jako końca zakresu".
Dlaczego więc ten (patrz drugi kod) działa, ale ten (pierwszy kod) nie działa?
#include <algorithm>
#include <iterator>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> coll1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// copy the elements of coll1 into coll2 by appending them
vector<int> coll2;
copy (coll1.cbegin(), coll1.cend(), // source
back_inserter(coll2)); // destination
vector<int> coll3;
copy (coll1.begin(), {},
back_inserter(coll3));
}
następujący kod jest od drugiej edycji C++ biblioteki standardowej.
Linia z "// koniec źródła" może być albo "istream_iterator()" lub po prostu "{}"
oba działa, ponieważ: cytat z książki
„Należy zauważyć, że od C++ 11 można przekazać puste nawiasy klamrowe zamiast domyślnego iteratora strumienia jako końca zakresu, ponieważ ten typ argumentu definiujący koniec zakresu źródłowego wywodzi się z poprzedniego argumentu, który definiuje początek zakresu źródłowego. "
/* The following code example is taken from the book
* "The C++ Standard Library - A Tutorial and Reference, 2nd Edition"
* by Nicolai M. Josuttis, Addison-Wesley, 2012
*
* (C) Copyright Nicolai M. Josuttis 2012.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*/
#include <iterator>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vector<string> coll;
// read all words from the standard input
// - source: all strings until end-of-file (or error)
// - destination: coll (inserting)
copy (istream_iterator<string>(cin), // start of source
{}, // end of source
back_inserter(coll)); // destination
// sort elements
sort (coll.begin(), coll.end());
// print all elements without duplicates
// - source: coll
// - destination: standard output (with newline between elements)
unique_copy (coll.cbegin(), coll.cend(), // source
ostream_iterator<string>(cout,"\n")); // destination
}
masz. {} po prostu oznacza domyślne tworzenie iteratorów; to znaczenie domyślnego konstruktora stream_iterator sprawiło, że jest on wyjątkowy w tym kontekście. Drugi to sztuczka, dobra sztuczka. – milesma
W dzisiejszych czasach iteratory zazwyczaj nie są wskaźnikami, nawet w przypadkach, w których mogą być (wektory i łańcuchy). –
@ T.C. Nawet jeśli nie są wskaźnikami, iteratory wektorowe i łańcuchowe są zwykle cienkimi owijkami wokół wskaźników, przynajmniej w zoptymalizowanych kompilacjach. Podstawowe założenia dla wydajnych iteratorów nie zmieniły się tak bardzo. Np. W przypadku libstdC++ to cienkie opakowanie nazywa się __gnu_cxx :: __ normal_iterator. –