Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Implicit conversion error with conversion operator

39 views
Skip to first unread message

Juha Nieminen

unread,
Apr 23, 2018, 5:58:47 AM4/23/18
to
Consider the following code:

//------------------------------------------------------------
struct Coords { int x, y; };

struct Foo
{
Foo(Coords);
};

struct Bar
{
operator Coords() const;
};

const Foo foo = Bar();
//------------------------------------------------------------

When I try to compile it with (a recent version of) clang, I get the error:

----------------------------------------------------------------------
error: no viable conversion from 'Bar' to 'const Foo'
const Foo foo = Bar();

candidate constructor not viable: no known conversion from 'Bar' to
'Coords' for 1st argument
Foo(Coords);

candidate function
operator Coords() const;
----------------------------------------------------------------------

It's giving the operator Coords() function as a candidate function, but
doesn't explain why it's rejecting it.

Tim Rentsch

unread,
Apr 23, 2018, 3:40:48 PM4/23/18
to
Juha Nieminen <nos...@thanks.invalid> writes:

> Consider the following code:
>
> //------------------------------------------------------------
> struct Coords { int x, y; };
>
> struct Foo
> {
> Foo(Coords);
> };
>
> struct Bar
> {
> operator Coords() const;
> };
>
> const Foo foo = Bar();
> //------------------------------------------------------------
>
> When I try to compile it with (a recent version of) clang, I get the error:
>
> error: no viable conversion from 'Bar' to 'const Foo'
> const Foo foo = Bar();
>
> candidate constructor not viable: no known conversion from 'Bar' to
> 'Coords' for 1st argument
> Foo(Coords);
>
> candidate function
> operator Coords() const;
>
> It's giving the operator Coords() function as a candidate function, but
> doesn't explain why it's rejecting it.

I must admit I find the rules for implicit conversions in C++ to
be confusing. So what I have to offer is just some observations
that may be helpful.

(1) I tried with g++, it gave a different message.

(2) You can do what you want with one of these (some may not
work with older C++'s):

const Foo foo( Bar() );
const Foo foo{ Bar() };
const Foo foo = { Bar() };

(3) If we had declared foo as 'Foo foo;' then

foo = Bar();

doesn't work, but

foo = Foo( Bar() );

or

foo = { Bar() };


does. This behavior matches my (ancient and perhaps now outdated)
understanding that only one implicit conversion is allowed.

Andrey Tarasevich

unread,
Apr 26, 2018, 3:59:43 PM4/26/18
to
On 4/23/2018 2:58 AM, Juha Nieminen wrote:
> Consider the following code:
>
> //------------------------------------------------------------
> struct Coords { int x, y; };
>
> struct Foo
> {
> Foo(Coords);
> };
>
> struct Bar
> {
> operator Coords() const;
> };
>
> const Foo foo = Bar();
> //------------------------------------------------------------
>
> When I try to compile it with (a recent version of) clang, I get the error:
>

Implicit conversion sequences in C++ are allowed include at most _one_
user-defined conversion. In your initialization above you are expecting
_two_ user-defined conversions to take place: Bar-to-Coords and
Coords-to-Foo. This is not allowed.

--
Best regards,
Andrey Tarasevich
0 new messages