为什么不对转换构造函数进行隐式转换?

Jon*_*Mee 3 c++ constructor implicit-conversion typecast-operator explicit-conversion

所以我有这个代码:

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;
};
Run Code Online (Sandbox Code Playgroud)

我本以为Foo foo = Bar(13)会使用我的隐式转换然后转换构造函数.但它错误:

错误:从请求转换Bar为非标量类型Foo

这工作正常:Foo foo(Bar(13)).为什么我的隐式转换用于显式转换构造,而不用于隐式转换构造?

我从https://en.cppreference.com/w/cpp/language/copy_initialization获得的规则说:

转换的结果,如果使用转换构造函数,则是prvalue表达式,然后用于直接初始化对象

son*_*yao 8

首先从隐式转换Barlong long,并从所述一个long longFoo都是用户定义的转换.

Foo foo = Bar(13);执行拷贝初始化,编译器会尝试转换BarFoo隐.需要两个隐式转换,即转换Barlong long转换然后转换long longFoo.但在一个隐式转换序列中只允许一个用户定义的转换.

隐式转换序列按以下顺序包含以下内容:

1)零个或一个标准转换序列;

2)零或一个用户定义的转换;

3)零个或一个标准转换序列.

用户定义的转换由零个或一个非显式单参数构造函数或非显式转换函数调用组成

Foo foo(Bar(13));执行直接初始化.Foo将检查构造函数,并通过重载决策选择最佳匹配.只需要一个隐式的用户定义转换(从Barlong long); 之后Foo::Foo(long long)被称为foo直接构建.

  • 在`Foo foo(Bar(13))`中只有一个隐式转换,从`Bar`到`long long`.但是`Foo foo = Bar(13)`要求将'Bar`转换为`long long`然后转换为`Foo`,以便`foo`可以被复制构造. (2认同)