advanced

Capturing perfectly-forwarded objects in lambdas -- Vittorio Romeo

Does [x = std::forward<decltype(x)>] behave like you expect?

capturing perfectly-forwarded objects in lambdas

by Vittorio Romeo

From the article:

Perfect forwarding and forwarding references allow developers to write generic template functions that retain the lvalueness/rvalueness of passed arguments [...] Let's try to use auto&&, std::forward and C++14's generalized lambda capture syntax to implement our desired semantics. [...] What we really want to do is:

  • Capture by copy if a is an rvalue reference.
  • Capture by reference if a is an lvalue reference.

[...]

Technical Debt - More Captureless Lambda Fun -- Adi Shavit

More interesting facts about captureless lambdas.

Technical Debt

by Adi Shavit

From the article:

The series on captureless lambdas generated some interesting comments.  
The articles discusses converting captureless lambdas into function pointers without explicitly specifying the cast-to type, calling conventions and standard conformance and a special callbackizing function for capturing lambdas.

Compose and curry as folds--Nick Athanasiou

With the next version of C++.

Compose and curry as folds

by Nick Athanasiou

From the article:

In a previous post we introduced C++17 fold expressions and described a way to extend them for arbitrary callables. Implementation details don’t matter for what we’re elaborating on here but it should be clear that (given the tools we developed) the following is possible:

(Op<F>(args) + ...)
(... + Op<F>(args))

Infographics: Operation Costs in CPU Clock Cycles--“No Bugs” Hare

A very interesting article about the cost of our basic operations.

Infographics: Operation Costs in CPU Clock Cycles

by “No Bugs” Hare

From the article:

Whenever we need to optimise the code, we should profile it, plain and simple. However, sometimes it makes sense just to know ballpark numbers for relative costs of some popular operations, so you won’t do grossly inefficient things from the very beginning (and hopefully won’t need to profile the program later �� )...

Terminators--Adi Shavit

Do you know how a program ends?

Terminators

by Adi Shavit

From the article:

A GraphViz diagram that shows both normal and unexpected program termination flows in C++.

There are multiple ways a C++ program may terminate. These include both normal and unexpected termination.
This GraphViz diagram shows the program termination flows as defined by the standard...

checking expression validity in-place with C++17--Vittorio Romeo

An introduction to the world of C++17.

checking expression validity in-place with C++17

by Vittorio Romeo

From the article:

When writing generic code, it is sometimes useful to check whether or not a particular SFINAE-friendly expression is valid (e.g. to branch at compile-time). Let's assume that we have the following class declarations...

struct Cat
{
    void meow() const { cout << "meow\n"; }
};

struct Dog
{
    void bark() const { cout << "bark\n"; }
};

...and that we would like to write a template function make_noise(x) that calls x.meow() and/or  x.bark() if they are well-formed expressions:

template <typename T>
void make_noise(const T& x)
{
    // Pseudocode:
    /*
        if(`x.meow()` is well-formed)
        {
            execute `x.meow();`
        }
        else if(`x.bark()` is well-formed)
        {
            execute `x.bark();`
        }
        else
        {
            compile-time error
        }
    */
}

In this article I'll show how to implement the pseudocode in:

C++11: using std::void_t and std::enable_if.

C++14: using boost::hana::is_valid and vrm::core::static_if.

C++17: using if constexpr(...), constexpr lambdas, and std::is_callable. This version will allow expression validity to be checked in-place (i.e. directly in the if constexpr predicate). Variadic preprocessor macros will also be used to make the user code easier to read and maintain...

Quick Q: Is there a case where ellipsis(vararg) should be preffered over variadic templates?

Quick A: There are several special cases where you may want that, but in general no.

Recently on SO:

Is there a case where ellipsis(vararg) should be preffered over variadic templates?

  1. If you provide a C API with C++ implementation, then templates are not an option for the API. Varargs are.
  2. If you need to support a compiler that doesn't support C++11 or newer standard, then variadic templates are not available. Varargs are.
  3. If you need a compilation firewall. I.e. you need to hide the implementation of the function from the header, then variadic template is not an option. Varargs are.
  4. On memory constrained systems (embedded), the different functions generated by the template may introduce too much bloat. That said, such systems are typically also real time, in which case varargs might also unacceptable due to branching and stack usage.