新C++标准:C++0x教程(一):导论

译者:yurunsun@gmail.com 新浪微博@孙雨润 新浪博客 CSDN博客日期:2012年11月12日

原作:Scott Meyers

这些是Scott Meyers培训教程《新C++标准:C++0x教程》的官方笔记,培训课程的描述请见 http://www.aristeia.com/C++0x.html,版权信息请见 http://aristeia.com/Licensing/licensing.html.

漏洞和建议请发送邮件到 smeyers@aristeia.com. 翻译错误请发送邮件给yurunsun@gmail.com (译者注).

1. 教程内容一览

  • 导论:历史和名词、C++98/C++0x的快速比较。
  • 面向所有开发者的特性auto关键词、基于范围的for关键词、lambdas, 线程等等
  • 库的改善:更多特性、基于tr1的功能、forward_list, unique_ptr等等
  • 类的开发者特性move语义、完美forwarding、委托/继承构造函数等等
  • 面向库的开发者特性:可变参数宏、decltype等等
  • 面向其他特性
  • 移除和废弃的特性

2. 导论

2.1 历史和名词

  • 1998: ISO C++标准正式启用 C++98
  • 2003: TC1(Technical Corrigendum 1)发布 C++03
  • 2005: TR1(Technical Report 1") 发布
  • 2008: 新C++标准草案
  • 2009: 一些C++0x特性开始逐渐通用
  • 2011: 新标准正式批准
  • 2012: TR2添加了新的标准库组件

编译器对C++0x支持进度表请见 http://www.aristeia.com/C++0x/C++0xFeatureAvailability.htm

2.2 gcc打开c++0x特性(译者增补部分)

  • 最好使用gcc4.6版本以上
  • Makefile增加编译选项 -std=gnu++0x
  • 如果使用qmake则在*.pro文件中增加编译选项QMAKE_CXXFLAGS += -std=gnu++0x

2.3 Copying和Moving

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语义,但这里预热几点:

  • Moving是新C++的关键思想:是对copy的优化操作
  • 新C++绝大多数标准类型都能被move:例如STL的容器
  • 有些类型不能被copy,但可以被move:例如stream, std::stream, std::unique_ptr等等

2.4 在一段样例程序中对比C++98与C++0x

我们写程序来列出下面书籍中前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
2.4.1 C++98程序的写法
#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));
}
2.4.1 C++0x程序的写法
#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));
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值