【问题标题】:Class variable gets implicitly casted to int despite explicit cast尽管显式转换,类变量仍被隐式转换为 int
【发布时间】:2019-05-16 18:49:40
【问题描述】:

我在 foo 类中编写了隐式转换运算符到 double 和显式转换运算符到 int,以及将 int 作为参数的函数。尽管被调用并没有强制转换 foo 对象代码被执行。

我使用 gcc PRETTY_FUNCTION 发现 foo 对象被强制转换为 double 然后转换为 int。

class foo
{
public:
    int x, y;
    foo(int x, int y) : x{x}, y{y} {}
    explicit operator int() {cout << __PRETTY_FUNCTION__ << "\n"; return x/y;}
    operator double() {cout << __PRETTY_FUNCTION__ << "\n"; return double(x)/double(y);}
};

void printint(int x)
{
    cout << x << "\n";
}

int main()
{
    foo var(1,2);
    printint(var);
}

我希望这不会因为显式运算符而编译,但它会编译并将 0 打印为 int(1/2)。

程序的输出是: foo::operator double() 0

【问题讨论】:

  • 那么如果类对象可以隐式转换为某物然后转换为int,那么显式运算符是什么意思,难道不应该阻止它的发生吗?

标签: c++


【解决方案1】:

来自cppreference

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

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

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

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

因此您的foo 可以转换为double (2),然后double 转换为int (3)。

如果您不希望代码编译,您还必须进行double 转换explicitexplicit 仅阻止您的 foo 在步骤 2 中转换为 int,但在整个序列中,转换仍然可以隐式完成。隐式转换可能很棘手,因为 (1) 和 (3) 单个用户提供的隐式转换 (2) 可能会产生意想不到的副作用。

【讨论】:

    【解决方案2】:

    当然它会使用double 转换运算符,然后将double 转换为intdouble 转换运算符可以被隐式调用。删除explicit,它不会先转换为double

    由于explicit,它不能使用explicit operator int()

    【讨论】:

    • 除非我在代码中没有说明,否则显式转换运算符的目的不是防止对象被转换为 int 吗?
    • @doromaanim 如果这是唯一可能的对话,是的。但是由于您的类可以隐式转换为double,并且double 可以隐式转换为int,这就是编译器选择做的事情。您的 explicit 对第二次转换没有影响,因为它不涉及您的课程
    猜你喜欢
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多