{"id":1031,"date":"2015-02-20T22:52:05","date_gmt":"2015-02-21T06:52:05","guid":{"rendered":"http:\/\/www.elbeno.com\/blog\/?p=1031"},"modified":"2015-06-30T21:16:32","modified_gmt":"2015-07-01T04:16:32","slug":"c11-no-brainer-features","status":"publish","type":"post","link":"https:\/\/www.elbeno.com\/blog\/?p=1031","title":{"rendered":"Adopting C++11: no-brainer features"},"content":{"rendered":"<p>C++11\/14 is a significant change from C++98\/03, and features like move semantics take a while to get used to. Also, people tend to be quite conservative about adopting new features (especially if they look unfamiliar). It took us in the games industry a while to move to C++ from C. But here are what I consider the no-brainer, programming-in-the-small things to adopt. Extra safety and expressiveness with zero runtime impact and pretty much no potential for misuse (never say never, but you&#8217;d really have to go out of your way).<\/p>\n<p><strong>1.<\/strong> <code>using<\/code> instead of <code>typedef<\/code><\/p>\n<p>Not only is it a whole two characters fewer to type, it&#8217;s easier to read in the common function pointer case, and you can use it for template aliases, which often saves a lot more verbosity in the rest of the code. No more <code>typename<\/code> everywhere! Compare:<\/p>\n<pre lang=\"cpp\">\r\n\/\/ old and busted: typedef\r\ntemplate <class T>\r\nstruct Foo\r\n{\r\n  \/\/ I can't typedef Foo<T>::type \r\n  \/\/ and I have to use typename everywhere\r\n  typedef T type;\r\n};\r\n\r\n\/\/ Typical usage: a function pointer\r\ntypedef void (*funcptr)(int);\r\n<\/pre>\n<pre lang=\"cpp\">\r\n\/\/ new hotness: using\r\ntemplate <class T>\r\nstruct Foo\r\n{\r\n  using type = T;\r\n};\r\n\r\n\/\/ This pattern is used a lot in C++14 STL\r\ntemplate <class T>\r\nusing foo_t = typename Foo<T>::type;\r\n\r\n\/\/ Function pointer is easier to read\r\nusing funcptr = void (*)(int);\r\n<\/pre>\n<p><strong>2.<\/strong> <code>static_assert<\/code><\/p>\n<p>Compile-time asserts; what&#8217;s not to like? Odds are you have a homegrown C++98 TMP version of this somewhere; now it&#8217;s part of the language. Extra safety for zero runtime cost.<\/p>\n<p><strong>3.<\/strong> <code>nullptr<\/code><\/p>\n<p>Again, extra safety for zero cost. Ditch your zeros and NULLs, and you can safely have functions overloaded on pointer and integral types.<\/p>\n<p><strong>4.<\/strong> scoped <code>enum<\/code>s (<code>enum class<\/code>)<\/p>\n<p>The compiler can help prevent accidental confusion between types, and the <code>enum<\/code> values don&#8217;t leak any more. Hurrah! (It&#8217;s like Haskell&#8217;s <code>newtype<\/code> for integers!)<\/p>\n<p><strong>5.<\/strong> forward declarations of <code>enum<\/code>s, underlying type for <code>enum<\/code>s<\/p>\n<p>This works on (new) scoped and (old) unscoped <code>enum<\/code>s alike. You don&#8217;t have to put in fake bit-width values to force the size of an <code>enum<\/code> any more, and you can hide the values separately from the declaration, so you don&#8217;t need to recompile everything when you add a value.<\/p>\n<p><strong>6.<\/strong> <code>override<\/code><\/p>\n<p>When (for example) the class you&#8217;re deriving from changes upstream, and now you&#8217;re accidentally not overriding a member function you thought you were&#8230; you&#8217;d really like to know that. With <code>override<\/code>, a bug that might take you a couple of hours to track down becomes a trivial-to-fix compile error. (Often mentioned in the same breath as <code>override<\/code> is <code>final<\/code>, and it&#8217;s fine, but much less usefully applicable.)<\/p>\n<p>Now, there are also a couple of things to stop using.<\/p>\n<p><strong>1.<\/strong> <code>rand()<\/code><\/p>\n<p>Stop using <code>rand()<\/code>. Really, it&#8217;s bad. Deep down, we always knew it was &#8220;bad&#8221; but maybe we convinced ourselves it was OK for &#8220;small&#8221;\/&#8221;quick-and-dirty&#8221; tasks. It isn&#8217;t. And now, it&#8217;s not any easier or faster than just doing the Right Thing with <code>&lt;random&gt;<\/code>. STL explains it all in <a href=\"http:\/\/channel9.msdn.com\/Events\/GoingNative\/2013\/rand-Considered-Harmful\">rand() considered harmful<\/a>.<\/p>\n<p><strong>2.<\/strong> <code>bind<\/code><\/p>\n<p>Lambdas supersede <code>bind<\/code> in every way. They&#8217;re more straightforward to write, easier to read, as powerful and at least as efficient if not more so, and just&#8230; you know, <em>not so weird<\/em>. And if you think lambdas take some getting used to, well, I don&#8217;t think I ever got used to <code>bind<\/code>&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>C++11\/14 is a significant change from C++98\/03, and features like move semantics take a while to get used to. Also, people tend to be quite conservative about adopting new features (especially if they look unfamiliar). It took us in the games industry a while to move to C++ from C&#8230;.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22,8],"tags":[],"class_list":["post-1031","post","type-post","status-publish","format-standard","hentry","category-cpp","category-programming"],"_links":{"self":[{"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1031","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1031"}],"version-history":[{"count":18,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1031\/revisions"}],"predecessor-version":[{"id":1049,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1031\/revisions\/1049"}],"wp:attachment":[{"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1031"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1031"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.elbeno.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1031"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}