Skip to content
Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

A problem with C++ lambdas?

elbeno, 18 February, 201530 June, 2015

C++ lambdas are wonderful for all sorts of reasons (especially with their C++14-and-beyond power). But I’ve run into a problem that I can’t think of a good way around yet.

If you’re up to date with C++, of course you know that rvalue references and move semantics are a major thing. At this point, there are a lot of blog posts, youtube/conference videos, and even books about how they work, and also about how forwarding references (formerly known as universal references) work with templates and std::forward to provide nice optimal handling of objects with move semantics.

In C++14 the ability to handle lambda captures with move semantics was added with generalized lambda capture; another piece of the puzzle as far as move-semantic completeness goes.

Another lesser-known but important piece of the complete picture is that class member functions can have reference qualifiers. (You can find this in the standard in section 9.3.1 [class.mfct.non-static]). This means that just as we write member functions with const modifiers, we can overload member functions with & or && modifiers and they will be called according to the value category of this. So you know when you can call std::move on data members safely.

Now, lambdas are conceptually like anonymous classes where the body is the operator() and the captured variables are the data members. And we can write lambdas with a mutable modifier indicating that the data members are mutable. (By far the common case is for them to be const, so the ordinary usage of const on a member function is inverted for lambdas.)

I said conceptually because it turns out they aren’t completely like that in at least one important way: lambdas can’t have reference qualifiers. Maybe for good reason – how would the compiler implement that? How would the programmer who wanted that behaviour specify the overloads (s)he’s wanting? These are tricky questions to answer well. But it is a problem – as far as I can tell so far, there is no way to know, inside a lambda, what the value category of the lambda object is. So the performance promise of the move semantic model falls down in the face of safety concerns: I don’t know whether I can safely move from a captured variable inside a lambda.

If anyone has any ideas about this, please let me know. Google and StackOverflow can tell me all about how move captures work with lambdas, but nothing about how to move things out of lambdas safely, or divine the value category of a lambda object. All the things I’ve tried have either not worked, or have resulted in suboptimalities of various kinds. (And frankly, if anything had worked, at this point I’d put it down to a compiler quirk and not to be relied on.)

As far as I can tell, it’s a definite shortcoming of C++ that there’s no way to do this in a compile-time, type-inferred, lambda-land way. I don’t see this in the core language issues – is it a known problem, or is there a known way to solve it that I don’t know yet?

C++ Programming

Post navigation

Previous post
Next post

Related Posts

Exercising Ranges (part 3)

1 July, 20151 July, 2015

(Start at the beginning of the series if you want more context.) So, I was going to implement monoidal_zip, and to do that, I would clone zip_with.hpp. So I did that. Eric’s a great library author, and the ranges code is pretty easy to read. For the most part I…

Read More

Rules for using <random>

8 April, 20153 June, 2025

These days, it’s easy to do the right thing. Don’t do this: Don’t use std::rand(). Ever. Don’t use std::random_shuffle() to permute containers. (Too easy to misuse; can use std::rand() under the hood.) Don’t use any kind of clock for a seed. Don’t use mod (%) to get a random value…

Read More

How a Bug Made Me a Better Programmer

1 March, 20091 March, 2009

This is the tale of a bug. A challenging bug I encountered some time ago, and which changed my career for the better. It was late 2004. I was lead multiplayer engineer on Goldeneye: Rogue Agent, a title which could charitably be described as mediocre, but I like to think…

Read More

Comments (3)

  1. Alan says:
    20 February, 2015 at 10:15 am

    We chatted about this already, but in case it spurs any other discussion…

    As i understand it after chatting, the problem is that you want to overload the () operator on the lambda, to be able to give an && version etc, but lambdas only let you specify a single chunk of code to associate with them.

    You could definitely make an old style functor that overloaded the () operator with different versions, and you might be able to hide away the details and make a nice declaration syntax with some macros. This is problematic though as I don’t think it would play nice with std::function, which doesn’t have that overloading exposed on it’s surface, so seems like you’d lose those overloads.

    I feel like it should be possible to make some construct similar to std::function that let you specify more than one lambda to live inside of it, for different operator () overloads, and since those overloads were exposed at the surface of the std::function type object, that it should be able to call the right lambda underneath.

    Doing it at the std::function level leaves a bit to be desired though. It seems like it’s place ought to be deeper, as a language construct. If so, the regular lambda we are used to now could be a special case of that more general object that allowed you to specify overloads.

    It’d be interesting to see the avenues you’ve attempted, even if they ended up being dead ends (:

  2. elbeno says:
    16 April, 2015 at 10:50 am

    Well I tried this again last night, and it seems like it might work after all. I’m not sure – maybe I ran into a compiler issue before or maybe it’s just user error.

    The piece I missed perhaps was that the lambda has to be mutable, or an rvalue-reference doesn’t make much sense.

  3. elbeno says:
    17 April, 2015 at 9:29 am

    I was wrong, I haven’t got it to work.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

©2026 Why is a raven like a writing desk? | WordPress Theme by SuperbThemes