Jump to content
  • Advertisement
Sign in to follow this  
taby

Learning C++11

This topic is 590 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'll eventually get to understand C++14, but for now I'm focusing on C++11.

 

One of the gems that I found in The C++ Programming Language, Fourth Edition is the range-for-statement (page 233 in the softcover edition, section 9.5.1), which trims down like 50 characters of code down to 10 characters.

 
#include <vector>
using std::vector;
 
#include <set>
using std::set;
 
#include <iostream>
using std::cout;
using std::endl;
 
int vecsum(const vector<int> &v)
{
    int s = 0;
    
    for(int x : v)
        s += x;
    
    return s;
}
 
int vecsum2(const vector<int> &v)
{
    int s = 0;
    
    for(vector<int>::const_iterator i = v.begin(); i != v.end(); i++)
        s += *i;
 
    return s;
}
 
int setsum(const set<int> &s)
{
    int sum = 0;
    
    for(int x : s)
        sum += x;
    
    return sum;
}
 
int setsum2(const set<int> &s)
{
    int sum = 0;
    
    for(set<int>::const_iterator i = s.begin(); i != s.end(); i++)
        sum += *i;
    
    return sum;
}
 
 
 
int main(void)
{
    vector<int> v;
    
    v.push_back(1);
    v.push_back(3);
    v.push_back(5);
    v.push_back(7);
    v.push_back(9);
    v.push_back(11);
    
    cout << vecsum(v) << endl;
    cout << vecsum2(v) << endl;
    
    set<int> s;
    
    s.insert(1);
    s.insert(3);
    s.insert(5);
    s.insert(7);
    s.insert(9);
    s.insert(11);
    
    cout << setsum(s) << endl;
    cout << setsum2(s) << endl;
    
    return 0;
}
 
 

Do you know of other gems?

Edited by sjhalayka

Share this post


Link to post
Share on other sites
Advertisement

How about this?

vector<int> v = { 1, 3, 5, 7, 9, 11 };

Are you actively using templates? If so, there is a lot of cool stuff, but if you are not writing template code then its pretty useless.

 

Move-semantics/operators are really useful (you really need to read them up in detail though), and theres lots of other good stuff regarding class constructors:

class Foo
{
	Foo(int, float)
	{
	}
}

class Bar :
    public Foo
{
	using Foo::Foo; // using constructor, now there is a Bar(int, float).
	
	Bar(int)
	{
	}

	Bar(float x) :
		Bar((int)x) // delegating constructors => calls Bar(int)
	{
	}
} 

Just stuff you can easily use in everyday-code, there is lots of specialized stuff like the template things I mentioned, lambas, std::bind etc...

Edited by Juliean

Share this post


Link to post
Share on other sites

How about this?

vector<int> v = { 1, 3, 5, 7, 9, 11 };

 

I get an error when I do that:

 

error: non-aggregate type 'vector<int>' cannot be initialized with an initializer list

 

vector<int> v = { 1, 3, 5, 7, 9, 11 };
 
I'm using g++ on macOS Sierra.
Edited by sjhalayka

Share this post


Link to post
Share on other sites

 

vector::const_iterator
 

 

You might want to look into 'auto'

 

 

Will do. Thank you. So far I know that auto in C++11 is not the same as auto in C (whatever version).

 

I found the following code using auto:

int vecsum3(const vector<int> &v)
{
    int s = 0;
    
    for(auto p = v.begin(); p != v.end(); p++)
        s += *p;
    
    return s;
}

It works like a vector<int>::const_iterator in this case I'd hope, automatically deducing the type. That's pretty cool too!

 

This also works:

int vecsum4(const vector<int> &v)
{
    int s = 0;
    
    for(auto p : v)
        s += p;
    
    return s;
}
Edited by sjhalayka

Share this post


Link to post
Share on other sites

I get an error when I do that:

 

Under VS2013+, this compiles, and the {}-initilization as used here should be perfectly legal C++11 code after all, so maybe its just something that your g++-version doesn't support it yet for some reason.

Share this post


Link to post
Share on other sites

How about this?

vector<int> v = { 1, 3, 5, 7, 9, 11 };

 
I get an error when I do that:
 
error: non-aggregate type 'vector<int>' cannot be initialized with an initializer list
 
vector<int> v = { 1, 3, 5, 7, 9, 11 };
 
I'm using g++ on macOS Sierra.


My guess is you didn't include <vector> or you didn't make std::vector visible. Try this:

#include <iostream>
#include <vector>

std::vector<int> v = { 1, 3, 5, 7, 9, 11};

int main() {
  for (auto i : v)
    std::cout << i << '\n';
}

Share this post


Link to post
Share on other sites

One other gem is the std::chrono high resolution timer in C++11 (page 123 in the fourth edition softcover):

auto t0 = high_resolution_clock::now();
 
size_t total = 0;

for(int i = 0; i < 100000000; i++)
    total += i;

auto t1 = high_resolution_clock::now();
    
auto ms = duration_cast<milliseconds>(t1 - t0).count();
    
cout << ms << endl;

The beautiful thing about std::chrono is that it works in Xcode 8.1, so you can use it to create millisecond timing on the iPod/iPad. Awesome.

 

Before std::chrono, one would need to use a different timer code on Windows and Linux. One must explicitly measure wall time in Linux, if I recall correctly.

Edited by sjhalayka

Share this post


Link to post
Share on other sites

This also works:

int vecsum4(const vector<int> &v)
{
    int s = 0;
    
    for(auto p : v)
        s += p;
    
    return s;
}

Note also that 'auto' in that case is an 'int' copying by value (which in the case of an int, is preferred).

But if you had something like, say, std::string, you'd probably rather have a reference - and usually you'd want it const, unless you are modifying it.

std::vector<std::string> myStrings = {"red", "blue", "green"};

for(const auto &str : myStrings}
{
    std::cout << str << std::endl;
}

Btw, while C++11 was a major addition, C++14 was a minor addition. C++17 will be another major addition, and C++20 (or whatever) will presumably be a small addition - this is the general 'tick-tock' upgrade plan they are going for.

 

The biggest new dealy with C++11 is move semantics (and the related 'rvalues'), which seem confusing (because people explain them poorly) but are actually really simple.

 

However, my favorite general syntax-related improvement is that you can now initialize class members directly in the class declaration:

class MyClass
{
    public:
    
    int myInt = 357;
    std::string myString = "Yay!";
};

Lambdas are also great! Functions (actually 'functors', because they are really classes in many cases) that you create inside other functions (among other things):

#include <iostream>

int main()
{
    int counter = 0;
    
    //-----------------------------------------------
    //vvv Lambda vvv
    
    auto doSomething = [&counter](const std::string &str)
    {
    	++counter;
    	
        std::cout << "Called 'doSomething' " << counter << " times. "
                  << "Calling with with '" << str << "' as a parameter." << std::endl;
    };
    
    //'doSomething' is a variable that *holds* an instance of the lambda to call later, like a function pointer.

    //-----------------------------------------------
    
    doSomething("Penguin");
    doSomething("Aardvark");
    
    for(const std::string &element : {"fire", "water", "earth", "wind"})
    {
        doSomething(element);
    }
    
    return 0;
}

[Test the code right in your browser]

 

(Note that the lambda using what's called a "capture" has a reference to another variable ('counter')).

 

The general syntax looks like this:

int myFunction(int arg) { } //Regular function
            [](int arg) { } //Lambda

auto myFunction(int arg) -> int { } //Another way of writing regular functions (specifying the return type after the arguments)
             [](int arg) -> int { } //Demonstrating the same thing with lambdas

Lambdas in other languages are typically called 'closures' or 'anonymous functions'.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!