2

根据 N3337 工作草案(与已发布的 ISOC++11 标准最相似的草案),答案最多是一个。

N3337

最多一个用户定义的转换(构造函数或转换函数)被隐式应用于单个值。

[ 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 (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4编译main.cpp并使用Ubuntu 14.04.3 LTS中引用的语句运行a.out的结果,答案最多不是一个。

主.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 是否包含错误?

4

2 回答 2

5

这里没有执行双重转换。

您在两个不同的地方进行了两次单独的转换。

一种转换是在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;
}

您是否看到这里发生了任何双重转换?不,即使我们现在拥有两个翻译单元,与您开始使用的完全相同的代码。

于 2016-02-13T01:51:57.473 回答
2

int i=Bs();Bs::operator int()隐式调用。

return As()As::operator int()隐式 调用。

这是两个不同的表达方式。

于 2016-02-13T02:06:56.133 回答