在隐式类型转换期间最多可以隐式应用多少个用户定义的转换运算符?
At most how many user-defined conversion operator can be implicitly applied during an implicit type conversion?
根据工作草案 N3337(与已发布的 ISOC++11 标准最相似的草案),答案最多为一个。
N3337:
At most one user-defined conversion (constructor or conversion
function) is implicitly applied to a single value.
[ Example:
struct X {
operator int();
};
struct Y {
operator X();
};
Y a;
int b = a; // error
// a.operator X().operator int() not tried
int c = X(a); // OK: a.operator X().operator int()
—end example ]
但是根据用gcc编译main.cpp的结果 (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8. 4 和 运行 a.out 以及 Ubuntu 14.04.3 LTS[=35= 中引用的语句],答案最多不是一个
main.cpp:
#include <iostream>
struct As
{
operator int(){ std::cout<<"operator As::int()"<<std::endl; return 1; }
};
struct Bs
{
operator int(){ std::cout<<"operator Bs::int()"<<std::endl; return As(); }
};
int main()
{
int i=Bs();
return 0;
}
从终端编译和运行:
$ g++ -std=c++11 main.cpp
$ ./a.out
结果(输出):
operator Bs::int()
operator As::int()
我是不是误解了什么或者 N3337 错了还是 gcc 包含错误?
这里没有执行双重转换。
您在两个不同的地方发生了两次单独的转换。
一次转换在 B::operator int()
.
第二次转换在您的 main()
中。
让我们试着从逻辑上思考一下:
从您的翻译单元中完全删除 main()。您看到任何双重转化了吗?
没有
现在,让我们创建一个包含以下位的头文件,将其命名为 structures.H
:
struct As
{
operator int();
};
struct Bs
{
operator int();
};
现在,创建一个 structures.C
文件,其中包含以下每个运算符的内容:
#include <structures.H>
B::operator int(){ std::cout<<"operator As::int()"<<std::endl; return 1; }
A::operator int(){ std::cout<<"operator Bs::int()"<<std::endl; return As(); }
好的,你还看到这里有任何双重转换吗?号
现在,创建您的 main.C:
#include <structures.H>
int main()
{
int i=Bs();
return 0;
}
您看到这里发生了任何双重转换吗?不,即使我们现在拥有两个翻译单元,与您开始使用的代码完全相同。
int i=Bs();
隐式调用 Bs::operator int()
。
return As()
隐式调用 As::operator int()
。
这是两个不同的表达式。
根据工作草案 N3337(与已发布的 ISOC++11 标准最相似的草案),答案最多为一个。
N3337:
At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.
[ Example: struct X { operator int(); }; struct Y { operator X(); }; Y a; int b = a; // error // a.operator X().operator int() not tried int c = X(a); // OK: a.operator X().operator int() —end example ]
但是根据用gcc编译main.cpp的结果 (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8. 4 和 运行 a.out 以及 Ubuntu 14.04.3 LTS[=35= 中引用的语句],答案最多不是一个
main.cpp:
#include <iostream>
struct As
{
operator int(){ std::cout<<"operator As::int()"<<std::endl; return 1; }
};
struct Bs
{
operator int(){ std::cout<<"operator Bs::int()"<<std::endl; return As(); }
};
int main()
{
int i=Bs();
return 0;
}
从终端编译和运行:
$ g++ -std=c++11 main.cpp
$ ./a.out
结果(输出):
operator Bs::int()
operator As::int()
我是不是误解了什么或者 N3337 错了还是 gcc 包含错误?
这里没有执行双重转换。
您在两个不同的地方发生了两次单独的转换。
一次转换在 B::operator int()
.
第二次转换在您的 main()
中。
让我们试着从逻辑上思考一下:
从您的翻译单元中完全删除 main()。您看到任何双重转化了吗?
没有
现在,让我们创建一个包含以下位的头文件,将其命名为 structures.H
:
struct As
{
operator int();
};
struct Bs
{
operator int();
};
现在,创建一个 structures.C
文件,其中包含以下每个运算符的内容:
#include <structures.H>
B::operator int(){ std::cout<<"operator As::int()"<<std::endl; return 1; }
A::operator int(){ std::cout<<"operator Bs::int()"<<std::endl; return As(); }
好的,你还看到这里有任何双重转换吗?号
现在,创建您的 main.C:
#include <structures.H>
int main()
{
int i=Bs();
return 0;
}
您看到这里发生了任何双重转换吗?不,即使我们现在拥有两个翻译单元,与您开始使用的代码完全相同。
int i=Bs();
隐式调用 Bs::operator int()
。
return As()
隐式调用 As::operator int()
。
这是两个不同的表达式。