2013-12-07 5 views
2

У меня есть класс, называемый номером, и мне нужна помощь при перегрузке оператора.перегрузка << оператор с шаблоном для изменения вывода

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; 
} 

что путь я могу назвать соиЬ как это (я знаю, что я мог бы просто изменить шаблон Номера для двойного, но это не то, что я хочу):

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

однако это не скомпилировано. так что все равно использовать шаблоны? или альтернативное решение, отличное от простого создания нормальной функции?

+2

в общем случае вы должны использовать операторы слияния C++ вместо оператора cast() '' стиля ''. т.е. 'static_cast'. –

+0

Я просто сделал быстрый поиск в Google, и я думаю, что вы правы. Есть ли преимущества в стиле c-стиле? – XenoZergNid

+1

Да, я все еще иногда использую C-стиль, когда я ленив. Но я не думаю, что ленивость хорошая. Операторы слияния C++ намного безопаснее. static_cast прежде всего. –

ответ

1

Я думаю, вы думаете слишком сложно об этом и, как вы хотите его использовать, не сработает.

Когда вам это нужно, чтобы быть распашными, сделать это дважды, так что поэтому я добавил здесь новый член в()

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"; 
+0

большое спасибо. Я предпочел бы, чтобы я мог использовать мой метод, но это не похоже, что это возможно. – XenoZergNid

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 

удачи.

Смежные вопросы