有了新的标准,就有了新的做事方法,许多方法比旧的方法更好,但旧的方法仍然很好。同样明显的是,由于向后兼容性的原因,新标准并没有正式弃用太多。所以剩下的问题是:
哪些旧的编码方式肯定不如C++11风格,我们现在可以做什么呢?
在回答这个问题时,您可以跳过“使用自动变量”等显而易见的内容。
避免在C++11中编写基本算法的原因之一是lambdas与标准库提供的算法相结合的可用性。
我现在正在使用它们,并且令人难以置信的是,您经常通过使用count_if()、for_each()或其他算法来告诉您想要做什么,而不必再次编写该死的循环。
使用带有完整C++11标准库的C++11编译器时,你再也没有理由不使用标准算法来构建你的。拉姆达,杀了它。
为什么?
在实践中(在我自己使用这种方式编写算法之后),感觉读一些用简单的单词构建的东西要比读一些必须解密才能知道意思的循环容易得多。也就是说,自动推导lambda参数将有助于使语法更容易与原始循环进行比较。
基本上,用标准算法编写的阅读算法要容易得多,因为单词隐藏了循环的实现细节。
我猜现在只有更高层次的算法需要考虑,因为我们有更低层次的算法可以构建。
有一次,有人认为应该通过const值来返回,而不是仅仅通过值来返回:
const
const A foo(); ^^^^^
这在C++98/03中基本上是无害的,甚至可能捕获了一些看起来像这样的错误:
foo() = a;
但是在C++11中禁止按const返回,因为它禁止移动语义:
A a = foo(); // foo will copy into a instead of move into it
所以只要放松和编码:
A foo(); // return by non-const value
您需要较少地实现swap的自定义版本。在C++03中,通常需要有效的非抛出swap,以避免代价高昂的抛出副本,并且由于std::swap使用两个副本,因此通常必须自定义swap。在C++中,std::swap使用move,因此重点转移到实现高效且非抛出的移动构造函数和移动赋值操作符上。由于这些默认设置通常很好,这将比C++03中的工作量少得多。
swap
std::swap
move
一般来说,很难预测哪些习语会被使用,因为它们是通过经验创造出来的。我们可以期待“有效的C++11 ”可能在明年,而“ C++11编码标准”只在三年内,因为必要的经验还没有出现。
一旦您可以放弃0和NULL,而选择nullptr,请立即这样做!
0
NULL
nullptr
在非泛型代码中,使用0或NULL并不是什么大问题。但是,一旦您开始在泛型代码中传递空指针常量,情况就会迅速改变。当您将0传递给template<class T> func(T)时,T被推导为int,而不是空指针常量。并且在此之后不能将其转换回空指针常量。如果宇宙只使用nullptr,这些问题就不会存在。
template<class T> func(T)
T
int
C++11不反对将0和NULL作为空指针常量。但您应该编写代码,就像它确实存在一样。
安全布尔习语&rarr;explicit operator bool()。
explicit operator bool()
私有复制构造函数(boost:noncopyable)&rarr;X(const X&) = delete
X(const X&) = delete
用私有析构函数和虚继承模拟final类&rarr;class X final
class X final
final
std::auto_ptr
shrink_to_fit()
= delete
operator new
=delete
result_of
decltype
我想我会停在那里!
我不知道它的名称,但C++03代码经常使用以下构造来替换丢失的移动赋值:
std::map<Big, Bigger> createBigMap(); // returns by value void example () { std::map<Big, Bigger> map; // ... some code using map createBigMap().swap(map); // cheap swap }
这避免了由于复制省略与上面的swap相结合而导致的任何复制。
当我注意到使用C++11标准的编译器不再使以下代码出错时:
std::vector<std::vector<int>> a;
因为应该包含操作符>>,我开始跳舞。在早期的版本中,人们必须这样做
std::vector<std::vector<int> > a;
更糟糕的是,如果你曾经调试过这个程序,你就会知道由此产生的错误消息有多可怕。
然而,我不知道这对你来说是否“显而易见”。
按值返回不再是问题。通过移动语义和/或返回值优化(依赖于编译器),编码函数更加自然,没有开销或成本(大多数情况下)。