gpt4 book ai didi

c++ - 为什么可以编译隐式转换

转载 作者:太空宇宙 更新时间:2023-11-03 10:37:41 25 4
gpt4 key购买 nike

定义一些类,例如:

class Data{
public:
Data() = default;
Data(Data const&){
std::cout<<"invoked"<<std::endl;
}
};

class DataA: public Data{

};

class DataB {
public:
DataB() = default;
DataB(DataA const&){}
};

示例 1:

class Test{
public:
Test() = default;
Test(void*){}
};
int* ptr = nullptr;
Test t = ptr ; //complie ok
/*
void* tmp = ptr; //implicit convertion once
Test t = Test(tmp); //implicit convertion twice
*/

示例 2:

class Test{
public:
Test() = default;
Test(Data){
std::cout<<"a"<<std::endl;
}
};
DataA a;
Test t2 = a; //complie ok
/*
Data tmp = a; //implicit convertion once
Test t2 = Test(tmp); //implicit convertion twice
*/

enter image description here enter image description here enter image description here

示例 3:

class Test{
public:
Test() = default;
Test(DataB){}
};
DataA b;
Test t3 = b; //complie error
/*
DataB tmp = b; //implicit convertion once
Test t2 = Test(tmp); //implicit convertion twice
*/

示例3错误
g++:
enter image description here clang :
enter image description here

以上这些代码,都是隐式转换了两次

问题一:
c++标准说表达式只能隐式转换一次,为什么例1和例2都编译成功

问题二:
相对于例1和例2,为什么例3是编译错误,都是隐式转换了两次

最佳答案

The c++ standard said the expression can only implicit convertion once

事实并非如此。您可以进行无限制的标准转换。您所受限制的是用户定义的转换。您只能在一个转换序列中进行一次用户定义的转换。也就是说

Test t = Test(tmp);

具有零隐式转换,因为 Test(tmp) 是一个显式转换,并且拷贝是 eldied,因此它与 Test t(tmp); 相同。这也与第二个 block 中的 Test t2 = Test(tmp); 发生的情况相同。

Test t2 = a

aDataA,但是 DataAData,因为它派生自 Data,因此存在到 Data 的隐式转换。这意味着您只有一个用户定义的从 DataTest 的转换,所以这是允许的。

问题

Test t3 = b

b是一个DataA,但是Test取了一个DataB。这意味着您需要将 b 转换为 DataB,这是用户定义的转换,然后您需要将该 DataB 转换为 Test 这将是第二个用户定义的转换。这就是你得到错误的原因。如果你这样做了

Test t3 = DataB(b);

然后它将编译,因为只有一个隐式用户定义的转换(您可以根据需要拥有任意多个显式转换)。

关于c++ - 为什么可以编译隐式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57675870/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com