首页 > 解决方案 > 为什么这不对转换构造函数进行隐式转换?

问题描述

所以我有这个代码:

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;
};

我原以为Foo foo = Bar(13)会使用我的隐式强制转换,然后使用转换构造函数。但它错误

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

不过,这很好用:Foo foo(Bar(13)). 为什么我的隐式转换用于显式转换构造,而不用于隐式转换构造?

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

转换的结果,如果使用了转换构造函数,则为纯右值表达式,然后用于直接初始化对象

标签: c++constructorimplicit-conversiontypecast-operatorexplicit-conversion

解决方案


首先从 to 的隐式转换和从to的Bar隐式转换都是用户定义的转换。long longlong longFoo

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

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

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

2) 零次或一次用户自定义转换;

3) 零或一标准转换序列。

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

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


推荐阅读