Reputation: 38919
So I have this code:
struct Foo {
Foo() { cout << "default\n"; }
Foo(const long long) { cout << "implicit\n"; }
};
struct Bar {
Bar(const short param) : param(param) {}
operator long long() const { return static_cast<long long>(param); }
const short param;
};
I would have thought that Foo foo = Bar(13)
would have used my implicit cast and then the converting constructor. But it errors:
error: conversion from
Bar
to non-scalar typeFoo
requested
This works fine though: Foo foo(Bar(13))
. Why is my implicit cast used for explicit converting construction, but not for implicit converting construction?
The rules I got from https://en.cppreference.com/w/cpp/language/copy_initialization say:
The result of the conversion, which is a prvalue expression if a converting constructor was used, is then used to direct-initialize the object
Upvotes: 3
Views: 209
Reputation: 172884
Firstly the implicit conversion from Bar
to long long
, and the one from long long
to Foo
are both user-defined conversion.
Foo foo = Bar(13);
perform copy initialization, the compiler will try to convert Bar
to Foo
implicitly. Two implicit conversions are required, i.e. converting Bar
to long long
and then converting long long
to Foo
. But only one user-defined conversion is allowed in one implicit conversion sequence.
Implicit conversion sequence consists of the following, in this order:
1) zero or one standard conversion sequence;
2) zero or one user-defined conversion;
3) zero or one standard conversion sequence.
A user-defined conversion consists of zero or one non-explicit single-argument constructor or non-explicit conversion function call
Foo foo(Bar(13));
performs direct initialization. The constructors of Foo
would be examined and the best match is selected by overload resolution. Only one implicit user-defined conversion (from Bar
to long long
) is required; after that Foo::Foo(long long)
is called to construct foo
directly.
Upvotes: 8
Reputation: 44238
As you use copy initialization then according to documentation
In addition, the implicit conversion in copy-initialization must produce T directly from the initializer, while, e.g. direct-initialization expects an implicit conversion from the initializer to an argument of T's constructor.
emphasis is mine. This is not the case.
Upvotes: 2