Giter Club home page Giter Club logo

cpp-templates-2nd--'s Introduction

CPP-Templates-2nd--

《C++ Templates 第二版》中文翻译,和原书排版一致,第一部分(1至11章)已完成,第二部分请参见:https://github.com/r00tk1ts/cpp-templates-2nd。 第三部分第18,19,20,21,22,23,24,25章完成。其余内容逐步更新中。 个人爱好,发现错误请指正

一个效果图: image

cpp-templates-2nd--'s People

Contributors

gungler avatar walton1128 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cpp-templates-2nd--'s Issues

P113-std::cref()

这里语法有误,印刷版已经修正(2018年5月第1版 人民邮电出版社)
image

更正为:

if (isless(std::cref(s), "world")) ... // ERROR
if (isless(std::cref(s),  std::string("world"))) ... // ERROR

P38-Deduction Guides

这里对Stack stringStack = "bottom";不合法的情景解读有误
image
原文的说法是:

However, by language rules, you can't copy initialize (initialize using =) an object by passing a string literal to a constructor expecting a std::string. So you have to initialize the stack as follows:

Stack stringStack{"bottom"};    //Stack<std::string> deduced and valid

直译如是:
然而,根据语言规则,你无法通过传递一个字符串字面量来拷贝初始化(使用=初始化语法)一个期望传递std::string的对象。因此,你不得不按下面的方式初始化:Stack stringStack{"bottom"}; //Stack<std::string> deduced and valid

但我觉着这里作者的说法也不太对,上面的Stack stringStack = "bottom";之所以不合法,是因为类的初始化赋值语句实际上会调用copy constructor,但是copy constructor需要的是一个Stack<std::string>(Deduction Guides推断的Tstd::string),而const char [7]("bottom"字面量是const char [7]类型)无法转换成non-scalar typeStack<std::string>

我写了一段代码来验证:

template<typename T>
class Stack {
  private:
    std::vector<T> elems;
  public:
    Stack(const T& elem) : elems({elem}) {}
};

Stack(char const*) -> Stack<std::string>;

int main()
{
  Stack stringStack = "bottom";
  return 0;
}

用gcc 7.3.1编译报错如下:

$ g++ main.cpp -o main -std=c++17
main.cpp: In function ‘int main()’:
main.cpp:38:23: error: conversion from ‘const char [7]’ to non-scalar type ‘Stack<std::basic_string<char> >’ requested
   Stack stringStack = "bottom";
                       ^~~~~~~~

std::basic_string是std::string的alias

可以看到这里需要一个隐式转换的方法(即接受const char [7]的一个ctor但显然没有),所以编译失败。
但终归是能看到上面的Deduction Guide语句生效了,因为确实编译错误里认为stringStack是Stack<std::basic_string<char> >,尽管"bottom"是const char [7],与const char*有些区别,但依然可以被推导为std::string。当我把“bottom”换成const char *str = "bottom"; Stack stringStack = str;,再次编译,错误变成:

main.cpp: In function ‘int main()’:
main.cpp:36:23: error: conversion from ‘const char*’ to non-scalar type ‘Stack<std::basic_string<char> >’ requested
   Stack stringStack = str;
                       ^~~

也是符合预期的,因为被我手工decay成了const char *,Deduction Guide依然生效。

当把Deduction Guide语句删除后,并重新改为Stack stringStack = "bottom";编译错误迥然不同了:

main.cpp: In instantiation of ‘Stack<T>::Stack(const T&) [with T = char [7]]’:
main.cpp:36:23:   required from here
main.cpp:28:40: error: no matching function for call to ‘std::vector<char [7], std::allocator<char [7]> >::vector(<brace-enclosed initializer list>)’
     Stack(const T& elem) : elems({elem}) {}
                                        ^
......

省略了后面一大段,只看前面就可以看到T被推断为char[7],这里接受const T&参数的ctor语法编译就不通过了。而如果是const char *str = "bottom"; Stack stringStack = str;则可以编译通过,这也是符合模板推断预期的。

至于后面的花括号直接初始化语法当然是可行的(这里因为既不是aggregate class也没有initializer_list做参数的ctor,所以是匹配某个合适的ctor),这个就不展开了,实际上,用小括号语法直接调用构造器也可以完成const char*->std::string的推断:Stack stringStack("bottom");

P112-pass by value

这里,人民邮电出版社 2018年5月第1版已经修改为 pass s by value了。
image

P82-特殊成员函数的模板

Template member functions can be used wherever special member functions allow copying or moving objects.
结合上下文,这一句作者想要表达的意思应该是:只要类允许有copy/move ctor or assignment,那么这些特殊成员函数也是可以模板化的。

image

这里有个错别字,应该是“模板化”,另外更精准地叙述应该是:“限制存在场景”是“不易模板化”的一个例子

P87-模板参数模板

image

image

这里"class"是个关键字,结合上下文,是说C++11之前Cont只能由"class"关键字修饰,不能用typename

pdf 第58页的错别字

也可以将 class 定义成代表了一组下表的类型:

此处的“下表”应为“下标”

争议——2.8 typedef

image
我看了一下手里的实体书(2018年5月印刷),里面是没有这一冗余行的

感谢您的付出。

非常感谢您的付出。但还是冒昧的问一下,第12章-第17章的内容有打算翻译吗?

A Typo

image

此处应该是 编译期 而不是 编译器

image

->

image
->

P163-declvar()

image

这里有个笔误,应该是std::declvar()本身返回右值引用。

P14 typo

第14页的sts::string应为std::string.
image

P157-std::invoke

image

这里这样翻译可能会有读者难以理解。之所以不能用万能引用+完美转发,是因为函数体内对op调用了多次(是个while循环,迭代iterator),第一次执行后一旦使用了移动语义会对后续的调用产生副作用(即steal),也就是原文所说的subsequent iterations。

附录翻译

希望加入此书的翻译,现有英文纸质书一本。

类型推断中的类型转换

如果调用参数是按值传递的,那么只有退化(decay)这一类简单转换是被允许的:const 和 volatile 限制符会被忽略,引用被转换成被引用的类型,raw array 和函数被转换为相 应的指针类型。通过模板类型参数 T 定义的两个参数,它们实参的类型在退化(decay) 后必须一样。
粗体部分应该是:通过模板类型参数 T 定义的两个参数,它们的退化类型(ignore const/raw array->pointer)必须一样。
template
bool cmp( T t1, T t2 )
{
return *t1 < *t2;
}
int main()
{
int arr[ ] = { 1, 2,3 };
const int * p1 = arr;
int * p2 = arr;//lead toerror
const int * p2 = arr;//fine
cmp( p1, p2 );
}

有人知道 这个语法在哪边有说明吗 class function<_Res(_ArgTypes...)>

  template<typename _Res, typename... _ArgTypes>
    class function<_Res(_ArgTypes...)>

这个定义 里面 class function后面的 "<_Res(_ArgTypes...) “,从语法上讲,属于哪个部分。
哪里有讲为什么可以这么写。

有人跟我说这个是偏特化。但是我看特化里面。。这里应该是指定特化的,特别格式 。比如说某个模板参数是什么,应该跟析板参数 对应的。
他这个好像指出了模板参数的组织形式。(ps:我知道 他是为指明一个函数形式(signature))

讲知道 的大神指导一下

p337 PushBackRecT 实现

template<typename List, typename NewElement>
class PushBackRecT<List, NewElement, false>
{
    using Head = Front<List>;
    using Tail = PopFront<List>;
    using NewTail = typename PushBackRecT<Tail, NewElement>::Type;
public:
    using Type = PushFront<Head, NewTail>;
};

这里参数是不是反了,PushFront 接收的第一个参数是个 Typelist,第二个才是具体的 type。Head 是个具体的 type,而 NewTail 是个 Typelist


另外问一下作者还在翻译吗,这本书真的很棒,期待能看到完整版
看到 12 ~ 16 章的翻译了,感谢大佬们的无私奉献~

P73-花括号值初始化的补充说明

image

这里少了半句原文对花括号值初始化的补充说明。花括号值初始化的一个好处在于,如果类本身没有可用的默认构造器的话,提供一个initializer_list构造器也是可行的。

>Prior to C++17, this mechanism (which is still supported)
only worked if the constructor selected for the copyinitialization
is not explicit. In C++17, mandatory copy
elision avoids that limitation and either syntax can work,
but the braced initialized notation can use an initializerlist
constructor1 if no default constructor is available.

pdf 第27页中的拼写错误

会遇到 run-time error, 这是因为对 C 字符串,max(max(a, b), c)会创建一个用于返回的临时局
部变量,而在返回语句接受后,这个临时变量会被销毁,导致 man()使用了一个悬空的引用。
不幸的是,这个错误几乎在所有情况下都不太容易被发现。

上文中max被拼写成了man

P159-decltype(auto)声明ret

image
这里我解释一下,这种用法的场景是想在return之前做一些无关的别的事儿,需要把ret暂存起来,所以搞了个dummy对象,设计了个析构函数,想要做的事儿放在析构里做就行了,如此函数就无需定义ret了

【建议】中文版添加些评注信息

读书重在交流,尤其是这本非常具有深度的书,如果众多书友在读的过程中能够记录下自己的思考,疑问点,评注等,
然后集中一起,可以相互看见,那么这会大大扩展这本书的价值。
【Tips】如果有可能,希望这份repo中能够看到批注信息。

我有个疑问,关键词explicit被翻译了, 可能不翻译理解起来更好

在原书P69, 您翻译的pdf P64, explicit 应该不被翻译更好理解吧,
在 C++17 之前,这一方式(目前依然被支持)只有在与拷贝初始化对应的构造函数不是被显 式定义的时候才有效。
在C++17之前, 这一方式(目前依然被支持)只有在拷贝初始化对应的构造函数不被定义成explicit时才有效
即使它有显式的构造函数也是这样。
即使它的构造函数被定义成explicit也可以工作

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.