首页 > 解决方案 > C++ 编译器在显示我的类对象时如何找到最接近的类型转换?

问题描述

我写了一个类Fraction,并希望显示 Fraction 对象std::cout

Fraction f(3, 5);
std::cout << f << std::endl;

我知道重载operator <<可用于此显示目的。但我也可以重载operator type()函数,当只有operator double()(let typebe double) 时,我仍然可以std::cout << f << std::endl

更重要的是,我还可以实现operator std::string(). 但是,当上面提到的 3 个重载运算符函数都存在时,没有显式类型转换,在做什么时调用哪一个std::cout << f << std::endl?这真的让我很好奇,这种未定义的行为是否取决于编译器的实现,或者是否有一些规则可以对最接近/最合适的函数进行评分?

要重现,请使用以下代码:

#include <iostream>
#include <string>

class Fraction
{
public:
    Fraction(int num, int den=1):
        numerator(num), denominator(den) {}
    
    operator double() const {
        std::cout << "[operator double()]";
        return numerator*1.0 / denominator;
    }

    operator std::string() const {
        std::cout << "[operator std::string()]";
        return std::to_string(numerator) + "/" + std::to_string(denominator);
    }

private:
    int numerator;
    int denominator;

#ifdef OVERLOAD_STREAM_OP
    friend std::ostream& operator << (std::ostream& os, const Fraction& frac);
#endif

};

#ifdef OVERLOAD_STREAM_OP
std::ostream& operator << (std::ostream& os, const Fraction& frac)
{
    std::cout << "[operator <<]";
    os << std::to_string(frac.numerator) << "/" << std::to_string(frac.denominator);
    return os;
}
#endif

int main()
{
    Fraction f(3, 5);
    double d = 4 + f;
    std::cout << "\n--- now let's print\n";
    std::cout << "f: " << f << std::endl;
    std::cout << "f: " << std::string(f) << std::endl;
    std::cout << d << std::endl;

    return 0;
}

我的 ubuntu 20.04 上的输出:

(base) zz@home% clang++ fraction.cpp
(base) zz@home% ./a.out 
[operator double()]
--- now let's print
f: [operator double()]0.6
f: [operator std::string()]3/5
4.6

标签: c++type-conversion

解决方案


推荐阅读