重载<<运算符与模板来改变输出

时间:2013-12-07 06:33:32

标签: c++ operator-overloading

我有一个名为number的类,我需要有关运算符重载的帮助。

template<class T>
class Number{
public:
    Number(T _numerator,T _denominator){
        numerator = _numerator;
        denominator = _denominator;
    }
    ~Number(){
        ;
    }
    T GetData(){
        return numerator/denominator;
    }
    friend std::ostream &operator<<(std::ostream &out, Number c)     //output
    {
        out << c.numerator/c.denominator;
        return out;
    }
    void SetData(T _numerator,T _denominator){
        numerator = _numerator;
        denominator = _denominator;
    }

private:
    T numerator;
    T denominator;
};

这就是我的工作,但我希望另一个运算符重载,如:

template<class X>
friend std::ostream &operator<<(std::ostream &out, Number c)     //output
{
    out << (X)c.numerator/(X)c.denominator;
    return out;
}

这样我可以像这样调用cout(我知道我可以将Number的模板更改为double,但这不是我想要的):

Number<int> t(10,23);
std::cout << t<double> << "\n";

然而,这不编译。 所以有没有使用这样的模板?或者除了创建正常函数之外的替代解决方案?

2 个答案:

答案 0 :(得分:1)

我认为你的想法太复杂了,你想用它的方式也行不通。

当你需要它为Double时,将它加倍,所以我在这里添加新成员为()

template<class T>
class Number{
public:
    Number(T _numerator,T _denominator){
        numerator = _numerator;
        denominator = _denominator;
    }
    ~Number(){
        ;
    }
    T GetData(){
        return numerator/denominator;
    }
    friend std::ostream &operator<<(std::ostream &out, Number c)     //output
    {
        out << c.numerator/c.denominator;
        return out;
    }
    void SetData(T _numerator,T _denominator){
        numerator = _numerator;
        denominator = _denominator;
    }

    template<typename U>
    Number<U> as(){
        return Number<U>(U(numerator), U(denominator));
    }

private:
    T numerator;
    T denominator;
};


Number<int> t(10,23);
std::cout << t.as<double>() << "\n";

答案 1 :(得分:1)

您可以通过多种方式接近您所寻找的内容。不幸的是,你想要的完全语法是不可能的,因为你想要的类型必须通过某些东西(无论是函数,构造对象,等等)固定。

Vinzenz向您展示了如何通过会员功能将其固定下来。这是你可以通过一个替代构造函数固定它的方法。

#include <iostream>

template<class T>
class Number
{
    // allow friending alternate types
    template<typename> friend class Number;

    friend std::ostream &operator<<(std::ostream &out, Number c)     //output
    {
        out << c.GetData();
        return out;
    }

public:
    Number(T _numerator = 0, T _denominator = 1)
        : numerator(_numerator)
        , denominator(_denominator)
    {
    }

    // constructor for alt-type conversion
    template<typename X>
    Number(const Number<X>& obj)
        : numerator(static_cast<T>(obj.numerator))
        , denominator(static_cast<T>(obj.denominator))
    {
    }

    // getter should be const
    T GetData() const
    {
        return numerator/denominator;
    }

    void SetData(T _numerator,T _denominator)
    {
        numerator = _numerator;
        denominator = _denominator;
    }

private:
    T numerator;
    T denominator;
};

int main()
{
    Number<int> num(10,5);      // regular construction
    Number<float> flt = num;    // alternate type construction

    // operator tests
    std::cout << num << '\n';
    std::cout << flt << '\n';
    std::cout << Number<double>(num) << std::endl; // temp construction

    return EXIT_SUCCESS;
}

<强>输出

2
2
2

祝你好运。