译者:[email protected] 新浪微博@孙雨润 新浪博客 CSDN博客日期:2012年11月12日
原作:Scott Meyers
这些是Scott Meyers培训教程《新C++标准:C++0x教程》的官方笔记,培训课程的描述请见 http://www.aristeia.com/C++0x.html,版权信息请见 http://aristeia.com/Licensing/licensing.html.
漏洞和建议请发送邮件到 [email protected]. 翻译错误请发送邮件给[email protected] (译者注).
auto
关键词、基于范围的for
关键词、lambdas, 线程等等forward_list
, unique_ptr
等等move
语义、完美forwarding、委托/继承构造函数等等decltype
等等编译器对C++0x支持进度表请见 http://www.aristeia.com/C++0x/C++0xFeatureAvailability.htm
-std=gnu++0x
QMAKE_CXXFLAGS += -std=gnu++0x
C++一直支持对象状态的拷贝,例如拷贝构造函数、赋值符号。 C++0x增加了对移动对象状态的支持:
Widget w1;
Widget w2(w1);
Widget w3;
Widget w4(std::move(w3));
临时对象是使用moving的首选:
typedef std::vector<T> TVec;
TVec createTVec(); // 工厂函数
TVec vt;
vt = createTVec(); // C++98中,将返回值copy给vt,然后销毁返回值
vt = createTVec(); // C++0x中隐式使用move请求
尽管后面会详细讨论move语义,但这里预热几点:
我们写程序来列出下面书籍中前20个最常用的单词:
Alice_in_Wonderland.txt War_and_Peace.txt
Dracula.txt The_Kama_Sutra.txt The_Iliad.txt
70544 words found.
Most common:
the 58272
and 34111
of 27066
to 26992
a 16937
in 14711
his 12615
he 11261
that 11059
was 9861
with 9780
I 8663
had 6737
as 6714
not 6608
her 6446
is 6277
at 6202
on 5981
for 5801
#include <cstdio> // easier than iostream for formatted output
#include <iostream>
#include <iterator>
#include <string>
#include <fstream>
#include <algorithm>
#include <vector>
#include <map>
typedef std::map<std::string, std::size_t> WordCountMapType;
WordCountMapType wordsInFile(const char * const fileName) { // for each word in file, return
std::ifstream file(fileName); // # of occurrences
WordCountMapType wordCounts;
for (std::string word; file >> word; ) {
++wordCounts[word];
}
return wordCounts;
}
struct Ptr2Pair2ndGT { // compare 2nd components of pointed-to pairs
template<typename It>
bool operator()(It it1, It it2) const {
return it1->second > it2->second;
}
};
template<typename MapIt> // print n most
void showCommonWords(MapIt begin, MapIt end, const std::size_t n) { // common words in [begin, end)
typedef std::vector<MapIt> TempContainerType;
typedef typename TempContainerType::iterator IterType;
TempContainerType wordIters;
wordIters.reserve(std::distance(begin, end));
for (MapIt i = begin; i != end; ++i) {
wordIters.push_back(i);
}
IterType sortedRangeEnd = wordIters.begin() + n;
std::partial_sort(wordIters.begin(), sortedRangeEnd, wordIters.end(), Ptr2Pair2ndGT());
for (IterType it = wordIters.begin(); it != sortedRangeEnd; ++it) {
std::printf(" %-10s%10u\n", (*it)->first.c_str(), (*it)->second);
}
}
int main(int argc, const char** argv) {
// take list of file names on command line, print 20 most common words within
WordCountMapType wordCounts;
for (int argNum = 1; argNum < argc; ++argNum) {
// copy map returned by wordsInFile (modulo compiler optimization)
const WordCountMapType results = wordsInFile(argv[argNum]);
for (WordCountMapType::const_iterator i = results.begin(); i != results.end(); ++i) {
wordCounts[i->first] += i->second;
}
}
std::cout << wordCounts.size() << " words found. Most common:\n" ;
const std::size_t maxWordsToShow = 20;
showCommonWords( wordCounts.begin(), wordCounts.end(),
std::min(wordCounts.size(), maxWordsToShow));
}
#include <cstdio>
#include <iostream>
#include <iterator>
#include <string>
#include <fstream>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <future>
using WordCountMapType = std::unordered_map<std::string, std::size_t>;
WordCountMapType wordsInFile(const char * const fileName) { // for each word in file, return # of occurrences
std::ifstream file(fileName);
WordCountMapType wordCounts;
for (std::string word; file >> word; ) {
++wordCounts[word];
}
return wordCounts;
}
// print n mostcommon words in [begin, end)
template<typename MapIt> //
void showCommonWords(MapIt begin, MapIt end, const std::size_t n) {
// typedef std::vector<MapIt> TempContainerType;
// typedef typename TempContainerType::iterator IterType;
std::vector<MapIt> wordIters;
wordIters.reserve(std::distance(begin, end));
for (auto i = begin; i != end; ++i) {
wordIters.push_back(i);
}
auto sortedRangeEnd = wordIters.begin() + n;
std::partial_sort(wordIters.begin(), sortedRangeEnd, wordIters.end(),
[](MapIt it1, MapIt it2){return it1->second > it2->second; });
for (auto it = wordIters.cbegin(); it != sortedRangeEnd; ++it) {
std::printf(" %-10s%10zu\n", (*it)->first.c_str(), (*it)->second);
}
}
int main(int argc, const char** argv) {
// take list of file names on command line, print 20 most common words within process files concurrently
std::vector<std::future<WordCountMapType>> futures;
for (int argNum = 1; argNum < argc; ++argNum) {
futures.push_back(std::async([=]{ return wordsInFile(argv[argNum]); }));
}
WordCountMapType wordCounts;
for (auto& f : futures) {
const auto results = f.get(); // move map returned by wordsInFile
for (const auto& wordCount : results) {
wordCounts[wordCount.first] += wordCount.second;
}
}
std::cout << wordCounts.size() << " words found. Most common:\n" ;
const std::size_t maxWordsToShow = 20;
showCommonWords( wordCounts.begin(), wordCounts.end(),
std::min(wordCounts.size(), maxWordsToShow));
}