• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
  • entries
    146
  • comments
    436
  • views
    197044

The New C++, Part 1 - auto

Sign in to follow this  
Followers 0
Washu

4435 views

In this short series of entries I'm going to cover some of the new things that have been introduced into the C++ programming language with the latest standard. I will not be covering everything, as much of the new functionality has yet to be adopted or implemented in existing compilers, or are things that you probably shouldn't be playing with unless you have a lot of experience with the language, such as variadic templates. This first entry is going to focus on one of the more useful things added to the new C++ standard, auto. It will also give you a preview of the new function definition syntax, which will come in handy in future episodes.

How We Got Here



It has been nearly 14 years since C++ was first standardized. That makes the C++ standard pretty young and at the same time pretty old. Especially when you consider that, from a language perspective, the core standard has not changed any in those 14 years.
There have been a couple of updates to the standard through those 14 years, but they were all optional updates. If you wished to implement a compliant C++ compiler, you needed to only implement the standard as described in the original document. Unfortunately, that's not as easy as it sounds. The C++ language is a language of corner cases, and it is actually not hard to see why when you grasp one of the underlying thought concepts of the C++ language committee: Reserved words are bad.

When you look through the C++ language you find that there are approximately 73 reserved words, and if you look closer you will see that many of those reserved words get reused in various contexts throughout the standard. For a quick and simple example, the "class" keyword changes its behavior depending on if it's used in a template declaration or to define/declare a type. That, of course, is not the only reason the language is hard to parse, but it is part of the reason.

There have been several updates to the standard that have clarified various parts of it, and the C++ Technical Report 1 (TR1) added a whole bunch of new libraries to the C++ standard library, including tuple types, array, various hashed containers, regular expressions, a whole slew of mathematical functions, and a whole bunch of new random number facilities. Of course, since these were library extensions none of them were mandatory, but some compilers attempted to implement most or all of TR1.

Working with an Example



For the purposes of this entry we'll be working with some basic code, and implementing various bits and pieces using the new C++11 standard. I'll be using the Visual Studio 2010 compiler for this, although GCC should also work. Clang will work with most of the examples, however they do not yet have lambda support in, so the final pieces on lambdas will not compile in clang. Yet.


#include
#include
#include

template
std::pair find_first_pair(Sequence1 const& seq1, Sequence2 const& seq2, MatchBinaryFunctor match)
{
for(typename Sequence1::const_iterator itor1 = seq1.begin(); itor1 != seq1.end(); ++itor1) {
for(typename Sequence2::const_iterator itor2 = seq2.begin(); itor2 != seq2.end(); ++itor2) {
if(match(*itor1, *itor2)) {
return std::make_pair(itor1, itor2);
}
}
}

return std::make_pair(seq1.end(), seq2.end());
}

bool is_equal_and_odd(int lhs, int rhs) {
return lhs == rhs && lhs % 2 != 0;
}

int main() {
int v1ints[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int v2ints[] = {13, 4, 5, 7};

std::vector v1(v1ints, v1ints + 10);
std::vector v2(v2ints, v2ints + 4);

std::pair::const_iterator, std::vector::const_iterator> p = find_first_pair(v1, v2, is_equal_and_odd);

std::cout<<*p.first<<":"<<*p.second<}

This is a fairly simple piece of code that really does only one thing: It searches two containers passed to it for the first entries that the match functor returns true on, and then returns a pair of iterators to those two elements. Otherwise it returns iterators to the end of each container.
If you run this piece of code you get the output "5:5", as that's clearly the first entries that match our function is_equal_and_odd.

Auto - The Formerly Most Useless Keyword Ever



Let's talk a bit about auto. Auto, prior to C++11, was one of those keywords you never saw, for good reason to. A variable declared auto had "automatic storage duration." Interestingly enough though, variables NOT declared static or extern ALSO had automatic storage duration. Which meant that the difference between "auto int a;" and "int a;" was literally nothing. So why did it exist? Because it was in C, and C is included in the C++ standard.

When it came time for work to start on C++11 one of the things desired was to add static type inference. Type inference is the ability for the TYPE of a variable to be figured out based on its context. Static type inference is static, thus the type of the variable doesn't change and it can be computed at compile time. Thus auto was repurposed to be used in this manner. Of course, when you now declare an auto variable you no longer provide a type, but you must provide an initializer expression whose type is compile time knowable. Thus you can now say auto a = 0; whose type will be integer (as that is the type of the literal 0). As such auto str = std::string("Hello world") clearly is declaring a variable of type std::string.

Unfortunately, you cannot use auto everywhere you might like to. Function parameters cannot be auto, templates are for that. Furthermore, when we get into them, lambda parameters also cannot be declared auto. That last one there is perhaps one my biggest issues with the new standard.

With that bit of knowledge under our belt and the above code to work with we can clearly see several areas where just some small changes using auto can make the code significantly simpler and easier to read. If we replace the iterators in the for loops, and the declaration of p in the main method with auto we get the following piece of code, which I'm sure you'll agree is much simpler:

#include
#include
#include

template
std::pair find_first_pair(Sequence1 const& seq1, Sequence2 const& seq2, MatchBinaryFunctor match)
{
for(auto itor1 = seq1.begin(); itor1 != seq1.end(); ++itor1) {
for(auto itor2 = seq2.begin(); itor2 != seq2.end(); ++itor2) {
if(match(*itor1, *itor2)) {
return std::make_pair(itor1, itor2);
}
}
}

return std::make_pair(seq1.end(), seq2.end());
}

bool is_equal_and_odd(int lhs, int rhs) {
return lhs == rhs && lhs % 2 != 0;
}

int main() {
int v1ints[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int v2ints[] = {13, 4, 5, 7};

std::vector v1(v1ints, v1ints + 10);
std::vector v2(v2ints, v2ints + 4);

auto p = find_first_pair(v1, v2, is_equal_and_odd);

std::cout<<*p.first<<":"<<*p.second<}

It is important to note that auto does not automatically handle referencing. If you desire a reference auto type, you must specify that you desire a reference. As a trivial example:

auto itor = seq1.begin(); // by value.
auto& itor = seq1.begin(); // by reference.

A Newly Functional Way

Of course, reading this over you can see that the code is still pretty hard to read. I mean, where does the return type end and the function name start? Quite far in, makes it not so easy for the brain to parse, eh? One of the new tidbits that came with C++11 was a little thing called decltype, which we'll get into later. As part of decltype though came something else quite useful as well: A new style of function decleration. For the first time you can now declare the return type of the function AFTER the parameter portion of the function. Of course, you must still provide something to prefix the function with... hello auto. The syntax is a bit wonky though, I must warn you smile.png.

template
auto find_first_pair(Sequence1 const& seq1, Sequence2 const& seq2, MatchBinaryFunctor match) -> std::pair
{
for(auto itor1 = seq1.begin(); itor1 != seq1.end(); ++itor1) {
for(auto itor2 = seq2.begin(); itor2 != seq2.end(); ++itor2) {
if(match(*itor1, *itor2)) {
return std::make_pair(itor1, itor2);
}
}
}

return std::make_pair(seq1.end(), seq2.end());
}

This is, surprisingly, a lot easier to read. You can immediately find the return type (everything after the arrow), and you can find the function decleration as well. What would really make this a lot nicer is if we could somehow get rid of that horrible template mess in the return type. Ahh well, more on that later.

5
Sign in to follow this  
Followers 0


2 Comments


Thanks for this very informative post.

I would like to point out the video coverage of the "Going Native 2012" Conference which unsurprisingly concentrated on the new C++11 standard. Featuring Bjarne Stroustrup, Herb Sutter, Stephan T. Lavavej and Andrei Alexandrescu among others as speakers.

http://channel9.msdn.com/Events/GoingNative/GoingNative-2012
0

Share this comment


Link to comment
Yes, I've seen those presentations. I've been following the development of the new standard for a number of years now, sometimes with glee, and sometimes with trepidation.

My purpose here is not to necessarily be a definitive guide to all of the new features of C++11, but more as an introduction and application of its more visible components that are immediately available.

Unfortunately, a lot of what is covered by those presentations isn't available even in modern compilers, or has very buggy support indeed. Examples include the standard threading library. Boost threads do the trick, but are in the wrong namespace. Other examples include the fences, barriers, and variadic templates.
0

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now