манипулятор с ++ - PullRequest
       20

манипулятор с ++

0 голосов
/ 26 мая 2010

У меня есть класс:

template<class T>
class matrix
{
private:
    int COLS,ROWS;
public:
    inline matrix(int r,int c){
        this->COLS=r;
        this->ROWS=c;
    }

    template<class T2>
    friend ostream& info(ostream& os);
};

Я пытался реализовать функцию info многими способами, но ни один из них не удался.

я хочу использовать его в основной функции

Matrix<int> M(10,20);

cout<<info<<M;

Я хочу вывести столбцы класса Matrix и информацию о строках.

Я столько раз пытался реализовать информацию о классе друга, но не смог.

Кто-нибудь может сказать мне, как это сделать?

извините, я забыл поставить << перегрузочную часть. </p>

template<class T2>
friend ostream& operator<< (ostream &out,matrix<T2> &cMatrix);

реализация:

template<class T2>
ostream & operator<<(ostream &out, matrix<T2> &cMatrix) {
    out<<cMatrix.getCOLS();// sorry for didn't put the get function, it's not easy to put code line by line here.
    out<<cMatrix.getROWS();
    return out;
}

Моя << работает работает весело. </p>

но когда я хочу использовать информацию, я получаю ошибки.

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

вот что я извлекаю:

template<class T2>
ostream& info(ostream& os,matrix<T2> &cMatrix)
{
    int cols=cMatrix.getCOLS();
    int rows=cMatrix.getROWS();
    os<<rols<<"X"<<rows<<"  matrix "<<endl;
    return os;
}

Ответы [ 4 ]

2 голосов
/ 26 мая 2010

Если вы хотите эмулировать манипуляторы наподобие cout << setw(8) << …, для этого нет стандартного средства, и это невозможно сделать только с помощью функции.

Манипуляторы, принимающие аргументы, являются фабричными функциями, которые создают специальные функторы. Возвращенный объект запоминает параметр для манипулятора и реализует operator<< для его использования.

В примере кода есть два отдельных подхода.

cout<<info<<M; // info changes cout somehow?

и

ostream& info(ostream& os,matrix<T2> &cMatrix) // info behaves like operator<<?

Первый подход, добавление состояния к cout, возможен, но слишком сложен для этого.

Второй подход напрашивается на вопрос, почему вы не просто называете это operator<< и все готово.

Альтернативно, вы можете позвонить второму напрямую: info(cout << "hello", M) << "world";

Если вы ищете синтаксис cout << info(M), который больше похож на манипулятор, вам нужно что-то вроде

struct print_info {
    Matrix &m;
    print_info( Matrix &in ) : m(in) {}
    friend ostream &operator<<( ostream &str, print_info const &pi ) {
         str << pi.m.getcols();
         …
    }
};

print_info info( Matrix &in )
    { return print_info( in ); }

Строго говоря, эта функция не нужна, но лучше не давать классу с такой специфической функцией такое общее имя, как info.

Но опять же, все это не нужно. Просто используйте переопределение <<, которое у вас есть.

1 голос
/ 26 мая 2010

Один из возможных подходов, если вам не нужно, чтобы он был липким:

class InfoPrinter {
    std::ostream& os_;
public:
    InfoPrinter(std::ostream& os) : os_(os) {}
    template<class T> std::ostream& operator<<(const Matrix<T>& m) {
        return os_ << m.getCols() << ", " << m.getRows();
    }
};

struct Info {} info;

InfoPrinter operator<<(std::ostream& os, const Info&) {
    return InfoPrinter(os);
}

Использование будет, например ,::1004*

std::cout << info << Matrix<int>(2,3);
0 голосов
/ 26 мая 2010

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

0 голосов
/ 26 мая 2010

Я считаю, что это может сработать, просто создав ostream& operator<<(ostream& os); в качестве члена вашего класса Matrix. Тогда вы можете пойти cout << M << endl;

...