Articles & Books

Fun with Reflection in C++ -- Jakie Kay

Jakie Kay explores in her recent blog post the borders of nearly unknown C++ features:

Fun with Reflection in C++

by Jakie Kay

From the article:

In my previous post, we learned about the current and future state of reflection in C++. But I left a few questions unanswered. Indeed, you may still be wondering why I care so much about reflection and if it has any useful applications for the average programmer. In this post, I’ll try to answer that question with real code examples using the two reference implementations of C++ reflection. I’ll explore the strengths of the two implementations, as well as the major limitations. These examples make heavy use of metaprogramming and C++17 features, so if you find yourself in unfamiliar territory while reading the code, I suggest supplementing this article with other resources.

When I refer to the reflexpr implementation, I’m talking about Matúš Chochlík’s fork of Clang which implements P1094, by Chochlík, Axel Naumann, and David Sankel.

When I refer to cpp3k, I’m talking about Andrew Sutton’s fork of Clang which implements P0590R0, by Sutton and Herb Sutter.

Quick Q: When should you ever use functions over functors in C++?

Quick A: They behave differently, it depends on what you need.

Recently on SO:

When should you ever use functions over functors in C++?

Functions support distributed overriding. Functors do not. You must define all of the overloads of a Functor within itself; you can add new overloads of a function anywhere.

Functions support ADL (argument dependent lookup), permitting overloading in the argument-type associated namespace. Functors do not.

Function pointers are a kind of type-erased stateless functor that is a POD, as evidenced by how stateless lambdas convert into it. Such features (POD, stateless, type erasure) are useful.

A true heterogeneous container in C++--Andy G

An interesting article as well as a nice demo!

A true heterogeneous container in C++

by Andy G

From the article:

Oftentimes I see questions StackOverflow asking something to the effect of

“Can I have a std::vector that holds more than one type?”
The canonical, final, never-going-to-change answer to this question is a thorough

“No”
C++ is a statically-typed language. A vector will hold an object of a single type, and only a single type.

“But…”
Of course there are ways to work around this...

Quick Q:Is there a way to mark a parent's virtual function final from a child class?

Quick A: No.

Recently on SO:

Is there a way to mark a parent's virtual function final from a child class without reimplementing it

No, you can't do it without reimplementing it. So just reimplement it:

struct Child : public Parent
{
    virtual void fn() override final { Parent::fn(); }
};

N.B. saying virtual ... override final is entirely redundant, final is an error on a non-virtual function, so you should just say:

    void fn() final { Parent::fn(); }

See http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rh-override

C++ User Group Meetings in May

The monthly C++ User Group listing at Meeting C++:

C++ User Group Meetings in May 2017

by Jens Weller

From the article:

The monthly overview on upcoming C++ User Group Meetings. Lots of meeting are already planned for May, even more should be announced in the coming weeks.

There are 2 new C++ User Groups: Minneapolis, Stockholm (LLVM).

Quick Q: shrink_to_fit() vs swap trick

Quick A: Are equivalent, but shrink_to_fit mark the intention.

Recently on SO:

shrink_to_fit() vs swap trick

The swap trick isn't actually constant-time. The cost of performing the actual swap is indeed O(1), but then there's the cost of the std::vector destructor firing and cleaning up all the allocated space. That can potentially have cost Ω(n) if the underlying objects have nontrivial destructors, since the std::vector needs to go and invoke those destructors. There's also the cost of invoking the copy constructors for all the elements stored in the initial vector, which is similarly Ω(n).

As a result, both approaches should have roughly the same complexity, except that shrink_to_fit more clearly telegraphs the intention and is probably more amenable to compiler optimizations.

QStringView Diaries: Masters Of The Overloads -- Marc Mutz

The third episode of the QStringView Diaries blog series is out, in which Qt developer Marc Mutz describes the ongoing work in implementing a string-view for QString data.

QStringView Diaries: Masters Of The Overloads

by Marc Mutz

From the article:

The last blog post in this series described how to use string-views. This post is about how to design one. In particular, it’s about QStringView‘s constructors. They evolved through a rapid succession of changes. These changes either fixed ambiguities between QString and QStringView overloads, or improved performance. And they all have the same solution: std::enable_if, the Swiss Army Knife for overload control.

This post will take you from where we naïvely started to where we made the impossible possible: overloading a function for arrays and pointers.

In case you missed them, here are the first two instalments:

QStringView Diaries: The Eagle Has Landed

QStringView Diaries: Advances in QStringLiteral

 

 

A serious bug in GCC -- Andrzej Krzemienski

In his recent blog post Andrzej described in detail about a bug he discovered in GCC.


A bug in GCC

by Andrzej Krzemienski

From the article:

This post is to inform you about a bug in GCC that may cause memory (or other resource) leaks in your valid C++ programs.

One of the pillars of C++ philosophy is what we often call RAII: if you use classes to manage resources, use constructors for allocating resources and destructors for releasing them, the language makes sure that whatever happens, however you use such classes the resources will get properly released.

 

Quick Q: Syntax of final, override, const with trailing return types

Quick A: The signature of the function is first.

Recently on SO:

Syntax of final, override, const with trailing return types

The correct syntax should be:

  • override and final should appear after the member function declaration, which including the trailing return type specification, i.e.
auto debug(ostream& os=cout) const ->ostream& override final;
  • override and final should not be used with the member function definition outside the class definition, so just remove them:
auto Derived::debug(ostream& os) const ->ostream&
{
  os << "dval: " << dval << endl;
  return os;
}