Reputation: 58392
How do you convert a Variant to bool in C++Builder 10?
In the old bcc32 compiler, I used the following code to check whether some generic TComponent was enabled:
if ((bool)GetPropValue(c, "Enabled", false))
do_something();
However, after upgrading to C++Builder 10 and enabling the new Clang-based compiler, I get the following error:
[CLANG Error] VclHelpers.cpp(1375): ambiguous conversion for C-style cast from 'System::Variant' to 'bool'
The full compiler messages indicate that 36 of Variant's conversion operators are considered legal candidates: operator double()
, operator wchar_t*
, etc.
Upvotes: 3
Views: 2853
Reputation: 58392
The problem is that Variant
provides too many conversion operators. In particular, the following operators make conversion to bool ambiguous:
__fastcall operator bool() const;
__fastcall operator signed char*();
__fastcall operator unsigned char*();
// etc. - Variant has similar operators for short, int, long, float, double...
// It calls these "by ref" conversions.
As I understand it, non-const overloads are normally preferred to const overloads, but with >1 alternative for non-const convertible-to-bool pointer conversions as well as a const bool conversion, the conversion is ambiguous.
It's probably a mistake for Variant
to have its conversions designed in such a way that they can't be used without ambiguity, but with help from @user2672165's and @Remy Lebeau's comments, there are several workarounds:
// Convert to int instead of bool.
if ((int)GetPropValue(c, "Enabled", false)) {}
// Make the Variant const, to avoid the ambiguous non-const conversions.
if (const_cast<const Variant>(GetPropValue(c, "Enabled", false))) {}
// Explicitly invoke the desired conversion operator.
if (GetPropValue(CheckBox1, "Enabled", false).operator bool()) {}
// Use TRttiProperty instead of Variant.
RttiContext ctx;
if (ctx.GetType(c->ClassType())->GetProperty("Enabled")->GetValue(c).AsBoolean()) {}
Upvotes: 4