Complicated situation with overloading function with QT / C ++ types

I am having a weird overloaded function problem that one of my work colleagues did, but we are both C ++ / QT newbies and cannot figure out the reason for this situation.

The situation is as follows:

We have an overloaded function:

foo(bool arg1 = false);
foo(const QVariant &arg1, const QString &arg2 = NULL, bool arg3 = false);

      

In the first case, we only have one optional bool argument passed as a value; On the second, we have one QVariant reference, an optional qstring reference, and a bool.

What happens at runtime is when I call for example:

foo("some_c++_string");

      

instead of using the 2nd option and exposing the string to a QVariant, it uses the first and probably ignores the argument! The weird thing is that it doesn't even complain about the lack of overloading for foo (char *) at compile time, for example! But if we do this:

 foo(QString("some_qt_string"));

      

it goes into the second overload as expected.

So the question is this: why in the world would the world decide to go for an overload that takes one optional argument of not the same type instead of using a second and tries to use a string argument as a QVariant?

It probably has to do with passing the arguments as a reference and specifying their default values, but I've tried several combinations and always got it wrong.

thank you for your time

+3


source to share


3 answers


This is due to the ordering of the implicit conversions. Converting a string literal to bool

requires only the standard conversion sequence: array-to-pointer conversion (get const char*

) and boolean conversion (get bool

).

On the other hand, converting a string literal to QVariant

requires a custom conversion sequence because it includes the ( QVariant

) class .

And for C ++ 11 13.3.3.2/2,

When comparing basic forms of implicit conversion sequences (as defined in 13.3.3.1)

  • The standard conversion sequence (13.3.3.1.1) is a better conversion sequence than a custom conversion sequence or ellipsis conversion sequence.

This means that the first overload is strictly better and is therefore chosen.




I would bet on creating Visual Studio. Otherwise, the construction

foo(QString("some_qt_string"));

      

doesn't even compile. This is because it QString("some_qt_string")

creates a temporary object, and in standard C ++, temporary files cannot bind to non-const lvalue references (which you do in the second overload). However, Visual Studio allows this as an extension.

+4


source


Why is the world daring to go for an overload that takes one optional argument of not the same type instead of using a second and tries to use a string argument as a QVariant?

Looking at the function signature:

foo (bool arg1 = false); foo (QVariant & arg1, QString & arg2 = NULL, bool arg3 = false);

The second overload is lvalue. If you pass const char*

, this would require creating a QVariant rvalue.

On the other hand, there is an overload function that takes a bool value, which is the best match, and is called.



You also said that if you do this:

foo(QString("some_qt_string"));  

      

the second is called. But it doesn't even have to compile. You are passing an rvalue to a function that takes an lvalue. I'm not sure which compiler you are using, but that is of course wrong. Set the warning level as high as possible and see what happens. Hope you don't ignore the compiler warnings;)

The simplest solution (and probably the best) is NOT to overload the function. Or at least not giving default arguments.

+3


source


The second overload takes QVariant

by reference as the first argument. You didn't pass QVariant

, so this overload should never be used. In fact, when you pass it QString

as the first argument, the second overload is still not viable and you should get a compiler error. I am assuming you are compiling with Microsoft VC and what you are observing is non-standard behavior that allows you to use the l-value reference of the temporary.

+2


source







All Articles