basics

Closer to Perfection: Get to Know C++11 Scoped and Based Enum Types -- Danny Kalev

Here's a nice intro and overview of one of the smaller features that makes C++11 safer.

Speaking of scoped and based enums, here's an interesting historical tidbit you may not know: These were initially co-proposed for C++ by an expert working on mission- and life-critical software and a large horizontal software company. Just goes to show the broad applicability of features like these, that matter where safety is critical and also help everyone.

Closer to Perfection: Get to Know C++11 Scoped and Based Enum Types

by Danny Kalev

C++ enum types pack a set of related constants in an intuitive and efficient user-defined type. Can you ask for more? With two new C++11 enhancements, namely scoped enums and based enums, the answer is "yes." Find out all about the recent facelift that C++11 enums underwent and learn how to refactor your code to benefit from the new enum features – without sacrificing performance or backward compatibility.

From the intro:

Enums are one of my favorite C++ features. They exemplify the notion of an efficient user-defined type without the heavy machinery of virtual functions, constructors, etc. (Compare C++ enums to other programming languages that still insist on using a full-blown class instead, and you’ll see what I mean.)

Yet, traditional enum types aren't flawless. ... C++11 addresses these issues with revamped enumerations that give you tighter control over the scope, size, and implicit conversions of enum types. Let's look at these new features more closely, and examine how they can improve both our code quality and frustration level.

Continue reading...

Quick Q: What can I do with a moved-from object? -- StackOverflow

Quick A: It's a valid object with an unspecified state, so start by using member functions that have no preconditions. For example, assign a new value to the object.

What can I do with a moved-from object?

Does the standard define precisely what I can do with an object once it has been moved from? I used to think that all you can do with a moved-from object is do destruct it, but that would not be sufficient...

Effective C++11 update -- Scott Meyers

This week, Scott Meyers posted a couple of updates on how C++11 is coming to one of the world's most-loved C++ book series -- Effective C++.

 

First, here's Scott's preamble about his approach to Effective C++11:

Effective C++11: Background

I've mentioned in some earlier posts that I plan to start writing a new book, Effective C++11.  The purpose of this post is to tell you a little bit about it. Lest there be confusion, let me emphasize that there is no book yet. If everything falls into place the way I hope it will, there will be a book about 10 months from now. If. I'm not making any promises. [...]

 

As a followup, Scott then posted an early draft list of candidate Items for Effective C++11 as part of this post:

Effective C++11: Content and Status

[...] At last year's C++ and Beyond, I gave a talk entitled "Initial Thoughts on Effective C++11." It had my usual guideline format. I also gave a talk on "Secrets of the C++11 Threading API," which consisted of observations about C++11's threading support. The material in those talks, combined with the feedback I got from giving them and mixed in with my experience explaining the idea of universal references, ultimately yielded the initial list of candiate Items for EC++11. The current snapshot of my vision for Effective C++11 is: [...]

At least a million developers are looking forward to your book, Scott!

No pressure.

Quick Q: How to use std:: pointers to implement data structures (say, a DAG)? -- StackOverflow

This is a good specific example of a very common question about how to use smart pointers in data structures:

weak_ptr VS shared_ptr in graph node parent list

I have a directed acyclic graph implemented by Graph and Node classes. Each node has a list of pointers to children and a list of pointers to parents. [...] The Child list uses std::shared_ptr so that nodes are kept in memory at least as long as they have parents. But I don't want a node to own its parents, so I used weak_ptr for the pointers to parents.

But then there was a problem with the algorithms...

 

Quick Q: Can an enum class be converted to the underlying type? -- StackOverflow

Quick A: Yes, but it requires an explicit cast. One of the key differences between enum and enum class: the latter has no implicit conversion to the underlying type.

Can an enum class be converted to the underlying type?

Is there a way to convert an enum class field to the underlying type? I thought this would be automatic, but apparently not.

enum class my_fields : unsigned { field = 1 };

unsigned a = my_fields::field;

That assignment is being rejected by GCC. error: cannot convert 'my_fields' to 'unsigned int' in assignment.

Quick Q: Why do 'auto x = my_x;' and 'X& x = my_x;' declare different types? -- StackOverflow

Quick A: Remember that you can add things like const and & to an auto type...

'auto' and explicit variable declaration behaving differently

I have something like this:

[...]

auto bar1 = foo.GetBar();
auto bar2 = foo.GetBar(); //address of bar2 != address of bar1. why?

Bar& bar3 = foo.GetBar();
Bar& bar4 = foo.GetBar(); //address of bar3 == address of bar4.

What's going on here?

In a nutshell: To move or not to move -- Martin Moene

[Ed.: If you're new to C++11 and wondering about move semantics, but find the longer "introductory" articles about it a little too detailed, here's a nice nutshell discussion with a simple example and good links for further reading.]

An introductory discussion of the new C++11 rvalue references in connection with move semantics:

To Move or Not To Move

by Martin Moene

I'm probably not the only one who needs some time to become familiar with the new C++11 rvalue references. Recall std::auto_ptr to take care of a resource's lifetime. It could catch you by surprise and cause the loss of something valuable with its unconditional move behaviour.

 

Well that's exactly why things changed in C++11.

Here are a few excerpts that helped me to put the new rvalue references in perspective. ...

Continue reading...

Quick Q: Can a lambda function be recursive? -- StackOverflow

Quick answer: Yes, use std::function.

This recent short question shows a concise and correct answer, along with a link to a previous more complex example.

Can lambda functions be recursive?

Here is a plain old recursive function:

int fak(int n)
{
    return (n <= 1) ? 1 : n * fak(n - 1);
}

How would I write such a recursive function as a lambda function?

[](int n) { return (n <= 1) ? 1 : n * operator()(n - 1); }
// error: operator() not defined

[](int n) { return (n <= 1) ? 1 : n * (*this)(n - 1); }
// error: this wasn't captured for this lambda function

Is there any expression that denotes the current lambda so it can call itself recursively?

Quick Q: If I have a T&&, why would I write std::move? -- StackOverflow

Here's a common question about the relationship between && and std::move. It includes links to related variations of the question -- aka duplicates, though they're not always exact duplicates and it's helpful to see answers on different aspects of the same core question.

In C++11, why use std::move when you have &&?

I recently attended a C++11 seminar and the following tidbit of advice was given.

when you have && and you are unsure, you will almost always use std::move

Could any one explain to me why [when you already have a T&& -- Ed.] you should use std::move as opposed to some alternatives and some cases when you should not use std::move?

Quick Q: How to use range-based for with std::map? -- StackOverflow

A common question from the SO archives:

C++11: How to use range-based for loop with std::map?

The common example for C++0x range-based for() loops is always something simple like this:

std::vector<int> numbers = { 1, 2, 3, 4, 5, 6, 7 };

for ( auto xyz : numbers )

{

     std::cout << xyz << std::endl;

}

In which case xyz is an int. But, what happens when we have something like a map? What is the type of the variable in this example:

std::map< foo, bar > testing = { /*...blah...*/ };

for ( auto abc : testing )

{

    std::cout << abc << std::endl;         // ? should this give a foo? a bar?

    std::cout << abc->first << std::endl;  // ? or is abc an iterator?

}

When the container being traversed is something simple, it looks like range-based for() loops will give us each item, not an iterator. Which is nice...if it was iterator, first thing we'd always have to do is to dereference it anyway.

 

But I'm confused as to what to expect when it comes to things like maps and multimaps.