C++ variant converting constructor with bool

Every version of the C++ standard has bugs. Hundreds of them.

C++ implementations aim to be useful, so they do not slavishly adhere to the published standard text. There's no reason to maintain bug-for-bug compatibility with a piece of paper.

(As an extreme example, until C++17 the standard technically required the <int> in std::vector<int> v; to be parsed as a header-name and then rejected because it is not inside a #include directive. It should go without saying that no compiler will do that.)

Cppreference also aims to be useful. So we do not maintain bug-for-bug compatibility with the standards either. When a piece of text first appeared in a piece of paper published by ISO is not useful (except for standard historians, perhaps); as programmers, what we care about is what we get when we use -std=c++17, or whatever your implementation's equivalent flag is. As a result, our documentation is for a hypothetical complete and correct implementation of each C++ standard plus all subsequent bugfixes and clarifications applicable to that standard.* We use the current implementations as evidence for what such a hypothetical implementation would do.

When there is no current implementation for a particular change, we evaluate the nature of the change to predict how the implementations would handle it. Core language changes intended to be retroactive are labeled as defect reports, which make the call easier (though sometimes they don't reach all the way back, and that is not in the labeling). Library changes do not come with consistently applied "DR" labels, however, so the call is more up to us.

In this particular case, while P0608 is not labeled as a defect report, it corrects an extremely questionable behavior in C++17 soon after its publication. Additionally, it is highly undesirable for code like std::variant<std::string, bool> x = "abcd"; to silently change meaning on the same implementation depending on the standard mode. Code relying on std::variant is also uncommon in the wild (this is partially why the committee even approved the "breaking" change in the first place). As a result, I predicted that the paper will eventually be applied retroactively and documented it accordingly.


*This is a change in philosophy from a few years back; as a result, we still have lots of cases where a bugfix is not treated as retroactive in the documentation but should be. They are being slowly cleaned up over time.


P0608R3 was adopted in San Diego. Its wording was applied to the working draft - you can see the new wording in [variant.ctor]/12.

As a part of that change, the motivating example:

variant<string, bool> x = "abc";

Does now hold a string (in c++20), whereas it used to hold a bool (in c++17). The meaning of this example changes between standard versions.

It's just that none of the standard libraries have implemented this change yet. It's very recent. It's listed as incomplete in both the libstdc++ and libc++ pages. But as you can see, there's tons of C++20 features that haven't been implemented yet either. The good news is, it's still early 2019 and there's plenty of time.

Tags:

C++

C++17

C++20