空花括号 {} 作为范围的结尾
empty curly bracket {} as end of range
我运行正在 XCode、Yosemite。
以下代码已编译但在 运行 时崩溃,为什么?
我在第二个 std::copy 中故意使用“{}”作为 "end of range"。
我试验了这段代码,因为有一个使用“{}”作为 "default constructed stream iterator as end of the range" 的工作示例。
那么,为什么那个(见第二个代码)可以工作,而这个(第一个代码)却失败了?
#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));
}
以下代码来自 C++ 标准库第二版。
带有“// end of source”的行可以是 "istream_iterator()," 或简单的“{},”
两者都有效,因为:引自书中
"Note that since C++11, you can pass empty curly braces instead of a default constructed stream iterator as end of the range. This works because the type of the argument that defines the end of the source range is deduced from the previous argument that defines the begin of the source range."
/* 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
}
第一个失败,因为你的迭代器类型不是 stream_iterator
。
对于 stream_iterator
情况,默认构造函数具有特殊含义 - EOF。表示容器末尾的迭代器不是默认构造的。 (在实践中,对于简单的容器,迭代器可以只是指针)。
除流迭代器之外的默认构造迭代器通常没有多大意义,并且在这种情况下不具有您想要的语义。
(除了流迭代器之外,其他一些来自 boost 的迭代器确实遵循与流迭代器相同的模式)。
我运行正在 XCode、Yosemite。
以下代码已编译但在 运行 时崩溃,为什么?
我在第二个 std::copy 中故意使用“{}”作为 "end of range"。
我试验了这段代码,因为有一个使用“{}”作为 "default constructed stream iterator as end of the range" 的工作示例。
那么,为什么那个(见第二个代码)可以工作,而这个(第一个代码)却失败了?
#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));
}
以下代码来自 C++ 标准库第二版。
带有“// end of source”的行可以是 "istream_iterator()," 或简单的“{},”
两者都有效,因为:引自书中
"Note that since C++11, you can pass empty curly braces instead of a default constructed stream iterator as end of the range. This works because the type of the argument that defines the end of the source range is deduced from the previous argument that defines the begin of the source range."
/* 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
}
第一个失败,因为你的迭代器类型不是 stream_iterator
。
对于 stream_iterator
情况,默认构造函数具有特殊含义 - EOF。表示容器末尾的迭代器不是默认构造的。 (在实践中,对于简单的容器,迭代器可以只是指针)。
除流迭代器之外的默认构造迭代器通常没有多大意义,并且在这种情况下不具有您想要的语义。
(除了流迭代器之外,其他一些来自 boost 的迭代器确实遵循与流迭代器相同的模式)。