I've been using previous version of C++ Builder and I decided to upgrade to 10.4 before 11.2 as I need C++17 compatibility. I'm already facing an issue with "scoped_lock" (C++ Builder 10.4 community edition => scoped_lock are missing (at least seems to be a path mess)) but now even that example from ccp_reference does not compile
#include <variant>
#include <string>
#include <cassert>
#include <iostream>
int main()
{
std::variant<int, float> v, w;
v = 42; // v contains int
int i = std::get<int>(v);
assert(42 == i); // succeeds
w = std::get<int>(v);
w = std::get<0>(v); // same effect as the previous line
w = v; // same effect as the previous line
// std::get<double>(v); // error: no double in [int, float]
// std::get<3>(v); // error: valid index values are 0 and 1
try {
std::get<float>(w); // w contains int, not float: will throw
}
catch (const std::bad_variant_access& ex) {
std::cout << ex.what() << '\n';
}
using namespace std::literals;
std::variant<std::string> x("abc");
// converting constructors work when unambiguous
x = "def"; // converting assignment also works when unambiguous
std::variant<std::string, void const*> y("abc");
// casts to void const * when passed a char const *
assert(std::holds_alternative<void const*>(y)); // succeeds
y = "xyz"s;
assert(std::holds_alternative<std::string>(y)); // succeeds
}
The compiler whines that there is no viable overload '=' at 2nd line of main (and further on). Basically, variant types do not seem to be usable at all. I've tried to make sure that c++17 is selected and I'm not using the "classic" version, but Clang, but nothing works. So am I missing something big or shall I just give up because that compiler is simply not at C++ 17 level?
std::variant
is broken in C++ Builder for some types. However, the compiler is intended to support C++17, and many C++17 features work. You could use boost::variant
instead.
There is a workaround in comments:
Issue: The assignment and constructor of Dinkumware std::variant checks that the value is assignable to exactly one type (_One_t<is_assignable, _Ty&, _Types&...>). This breaks those operations for a combination from int and double as they are assignable to each other.
Fix: I've changed _One_ta to _One_ts in file 'variant' lines 607, 611, 614, 918, 919, 920, and 926 and also _One_tc to _One_ts in code lines 624,628, and 631.
This limits these operators to the same types and works for me. I guess, that unambiguous conversions would be acceptable as well, but I've not checked the standard beyond looking to cppreference.com.