为什么允许对int和const int使用不同的转换函数?

时间:2018-06-20 09:16:55

标签: c++ c++11 type-conversion const language-lawyer

为什么允许以下内容用C ++编译?

#include<iostream>
using namespace std;

class mytest
{
public:    
    operator int()
    {
        return 10;
    }

    operator  const int()
    {
        return 5;
    }
};

int main()
{
    mytest mt;
    //int x = mt;    //ERROR ambigious 
    //const int x = mt; //ERROR ambigious
}

为什么当转换运算符的不同版本始终使用不明确时,允许编译不同版本(基于恒定性)有意义吗?

有人可以澄清我在这里缺少什么吗?

4 个答案:

答案 0 :(得分:18)

对于转换,它们是模棱两可的;但您可以明确地称呼他们。例如

int x = mt.operator int();
const int x = mt.operator const int();

答案 1 :(得分:5)

我认为从最严格的意义上讲,即使对const来说并没有多大意义,这也是合法的。

函数声明和函数类型之间有区别,并且它们没有相同的约束。

函数声明可能仅在返回类型或(自C ++ 17起)异常规范方面有所不同。但是,据我所知,关于函数 type 并没有这样的说法。

标准[class.conv.fct]将转换函数描述为具有某某形式(列出了三种选择),所有这些看起来都不像普通的函数声明,特别是它们显然没有返回类型。

状态为“ ”,功能类型为“ “不带参数的函数不返回conversion-type-id” ,但未提及转换函数声明具有返回类型之类的东西。相反,很明显列出的三种替代形式没有返回类型。

由于转换函数没有返回类型(在其声明中为...),因此它不会发生冲突。因此,我想,从最严格,最古怪的意义上来说,无论它是否有意义,它甚至都算是“合法的”。

如果您考虑一下,那么它也一定是合法的。一类很可能具有多个转换函数,可以转换为不同的事物(不仅仅是const有所不同)。这样的代码确实存在,因此有时这样做很有意义。
例如,您可能有一个类File可以转换为string(文件名)或handle_t(操作系统句柄),以防您想使用某些特定于操作系统的文件或包装器类不直接支持的奇异函数(想想writevteeepoll?)肯定是您希望使用的功能!
但是,如果我们将转换函数视为“正义函数”,那么它们的返回类型只会有所不同,这将使声明成为非法。所以...那是行不通的。

答案 2 :(得分:4)

  

为什么当转换运算符的使用总是导致模棱两可时,允许使用不同版本(基于常量性)(编译)是有意义的;

(除了高度人工的用例之外),通常没有任何意义,并且编译器可能会警告您:

prog.cc:12:25: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
     operator  const int()
                         ^

答案 3 :(得分:1)

我得出的结论是,不允许显式地编写仅根据返回值的恒定性而不同的对话运算符。编译过程明确禁止这样做的费用太昂贵

请记住,(成员)函数仅在返回类型上有所不同

class mytest
{
    int f();
    const int f();
};

被禁止:

  

错误:‘const int mytest :: f()’不能重载

只有转换操作符以operator开头才有区别。