首页 > 解决方案 > 当函数是类的朋友时,隐式转换在 C++ 中不起作用

问题描述

我在 C++ 中使用了一个库,它提供了一个特定的类,我们称之为 C1。我自己的类(C2)类似于 C1,有一个函数可以将 C1 转换为 C2,反之亦然。由于 C1 覆盖了我在 C2 中需要的所有运算符,我的想法是在 C2 中定义一个构造函数,它接受 C1 并调用转换函数。此外,将 C2 转换为 C1 的转换运算符被覆盖。据我了解,由于类型之间的隐式转换,编译器现在应该能够使用为 C1 编写的 C2 执行操作。但是,当我使用例如 std::cout 时,编译器无法看到 C2 可以转换为 C1 并且为 C1 实现了 << 运算符。显式铸造工作以及诸如 C2 a 之类的东西;C1 b = C2,所以我假设我正确地实现了转换。为了缩小问题范围,我创建了一个 mcve。

#include <iostream>

class C1 {
public:
    int v;
    C1(int v) {this->v = v;}
};

std::ostream& operator<<(std::ostream& s, const C1& c) {
    s << c.v;
    return s;
}

class C2 {
public:
    int v;
    C2(int count) {this->v = count;}
    C2(C1 c) {this->v = c.v;}
    operator C1() {return C1(this->v);}
};

int main() {
    C1 a(0);
    C2 b = a;
    C1 c = b;
    std::cout << a << b << c << std::endl;
    return 0;
}

但是当我在 C2 中移动 << 运算符时(在我正在使用的库中这样做),我得到“错误:'operator<<' 不匹配(操作数类型是 'std::ostream' {aka 'std::basic_ostream'} 和 'C2')"

相应的代码:

#include <iostream>

class C1 {
public:
    int v;
    C1(int v) {this->v = v;}
    friend std::ostream& operator<<(std::ostream& s, const C1& c) {
        s << c.v;
        return s;
    }
};

class C2 {
public:
    int v;
    C2(int count) {this->v = count;}
    C2(C1 c) {this->v = c.v;}
    operator C1() {return C1(this->v);}
};

int main() {
    C1 a(0);
    C2 b = a;
    C1 c = b;
    std::cout << a << b << c << std::endl;
    return 0;
}

为什么这不起作用?据我了解,编译器具有所有必需的信息: << 操作符有一个与 C1 一起使用的实现,并且可以将 C2 转换为 C1。

标签: c++operator-overloadingimplicit-conversionfriend-function

解决方案


推荐阅读