C++ variant converting constructor with bool

  • A+

On cppreference (4) the converting constructor is described as follows:

Converting constructor. Constructs a variant holding the alternative type T_j that would be selected by overload resolution for the expression F(std::forward<T>(t)) if there was an overload of imaginary function F(T_i) for every T_i from Types... in scope at the same time, except that:

  • An overload F(T_i) is only considered if the declaration T_i x[] = { std::forward<T>(t) }; is valid for some invented variable x;
  • If T_i is (possibly cv-qualified) bool, F(T_i) is only considered if std:remove_cvref_t<T> is also bool.

I am especially interested in the second bullet point regarding the bool. In the example it says, that:

std::variant<std::string, bool> y("abc"); // OK, chooses string; bool is not a candidate

I have now tested the same code with clang 7.0.0 (godbolt), gcc.8.2 (godbolt) and VS2017. And I am wondering why the contained alternative type is bool (for all the three compilers) and not std::string as described by cppreference. Is this a bug in the standard-libraries of all the three compilers?

I also found following document: P0608R3. Does it mean, that the modifications (the two bullet points) that cppreference lists are only proposed but not part of the official standard yet?


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.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: