Josh Kelley
Josh Kelley

Reputation: 58392

Converting a Variant to bool

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

Answers (1)

Josh Kelley
Josh Kelley

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

Related Questions