intermediate

Scott Meyers in Oslo: Friday, June 14

On Friday, June 14, Scott Meyers will be giving a talk open to the public at the Oslo C++ Users Group.

From Scott's announcement:

Lambdas vs. std::bind in C++11 and C++14

Scott Meyers

 

C++ developers have long had a need to bind functions and arguments together for a later call. This is what makes it possible to invoke member functions on objects inside STL algorithms. The same technology can be used to create custom callback functions and to adapt function interfaces to different calling contexts.

In C++98, such binding was accomplished via std::bind1st and std::bind2nd. TR1 added std::tr1::bind, which was promoted to std::bind in C++11. But C++11 also introduced lambda expressions, and they’re slated to become even more powerful in C++14. That means that there are now two mechanisms in C++ for binding functions to arguments for later calls: std::bind and lambda expressions. In this talk, Scott examines the pros and cons of each approach, comparing them in terms of expressiveness, clarity, and efficiency, and he comes to the conclusion that one should almost always be used instead of the other. But which one?

 

This presentation assumes a basic familiarity with std::bind and C++11 lambda expressions.

Quick Q: Should I return a const value? -- StackOverflow

Quick A: No.

Some authors wrote "Consider doing this" in C++98. The answer is now a definite "No" because it prevents move from returned values.

Isn't the const modifier here unnecessary?

The "Effective C++" Item 3 says "Use const whenever possible", and it gives an example like:

 

const Rational operator*(const Rational& lhs,
                            const Rational& rhs);

to prevent clients from being able to commit atrocities like this:

Rational a, b, c;
...
(a * b) = c;   // invoke operator= on the result of a*b!

But isn't the non-reference return value of functions allready a rvalue? So why bother doing this?

GotW #90 Solution: Factories -- Herb Sutter

The solution to the latest GotW problem is now available:

GotW #90 Solution: Factories (updated for C++11/14)

by Herb Sutter

From the article:

Guideline: A factory that produces a reference type should return a unique_ptr by default, or a shared_ptr if ownership is to be shared with the factory.

Guideline: A factory that produces a non-reference type should return a value by default, and throw an exception if it fails to create the object. If not creating the object can be a normal result, return an optional<> value.

GotW #6b Solution: Const-Correctness, Part 2 -- Herb Sutter

The solution to GotW #6b is now available:

GotW #6b Solution: Const-Correctness, Part 2 (updated for C ++11/14)

by Herb Sutter

From the article:

Option 1 is to use a mutex in the perhaps-soon-to-be-canonical “mutable mutex mutables” pattern:

// Option 1: Use a mutex

    double get_area() const {
        auto lock = unique_lock<mutex>{mutables};
        if( area < 0 )   // if not yet calculated and cached
            calc_area();     // calculate now
        return area;
    }

private:
    // ...
    mutable mutex  mutables;      // canonical pattern: mutex that
    mutable double area;          //   covers all mutable members

Option 1 generalizes well if you add more data members in the future. However, it’s also more invasive and generalizes less well if you add more const member functions in the future that use area, because they will all have to remember to acquire a lock on the mutex before using area.

Option 2 is to just change double to mutable atomic<double>. ...

 

GotW #4 Solution: Class Mechanics -- Herb Sutter

The solution to GotW #4 is now available:

GotW #4 Solution: Class Mechanics (updated for C++11/14)

by Herb Sutter

From the article:

... To see why, consider the following canonical forms for how operator+= and operator+ should normally be implemented for some type T.
T& T::operator+=( const T& other ) {
    //...
    return *this;
}

 

T operator+( T a, const T& b ) {
    a += b;
    return a;
}

Did you notice that one parameter is passed by value, and one by reference? That’s because if you’re going to copy from a parameter anyway, it’s often better to pass it by value, which will naturally enable a move operation if the caller passes a temporary object such as in expressions like (val1 * val2) + val3. We’ll see more on parameter passing in a future GotW. ...

.

GotW #3 Solution: Using the Standard Library (or, Temporaries Revisited) -- Herb Sutter

The solution to GotW #3 is now available:

GotW #3 Solution: Using the Standard Library (or, Temporaries Revisited) (updated for C++11/14)

by Herb Sutter

From the article:

With no other changes, simply using the standard find algorithm could do everything the range-based for loop did to avoid needless temporaries (and questions about them) [...] and it further increases our level of abstraction.

GotW #2 Solution: Temporary Objects -- Herb Sutter

The solution to GotW #2 is now available:

GotW #2 Solution: Temporary Objects (updated for C++11/14)

by Herb Sutter

From the article:

Because C++ naturally enables move semantics for returned values like this string object, there’s usually little to be gained by trying to avoid the temporary when you return by value. ... For example, if the caller writes auto address = find_addr( mylist, “Marvin the Robot” );, there will be at most a cheap move (not a deep copy) of the returned temporary into address, and compilers are allowed to optimize away even that cheap move and construct the result into address directly.

But what if you did feel tempted to try to avoid a temporary in all return cases by returning a string& instead of string? Here’s one way you might try doing it that avoids the pitfall of returning a dangling reference to a local or temporary object: [...] To demonstrate why this is brittle, here’s an extra question:

For the above function, write the documentation for how long the returned reference is valid.

Go ahead, we’ll wait. ...

The questions for #3 are posted for discussion:

GotW #3: Using the Standard Library (or, Temporaries Revisited)

 

 

Some Subtleties of Aliasing -- Andrew Koenig

Why "aliasing can cause paradoxical behavior"...

Some Subtleties of Aliasing

by Andrew Koenig

 

... As an example of a problem with this code, I suggested that it might be called by writing

 

scale(v, v[n]);

with the aim of dividing every element of v by v[n], but that this call would actually do something else entirely. From the comments on the article, I think that some readers were unclear about what that something else might be. To understand this call's behavior in detail, we have to look at the code more closely. ...