перегрузка << в шаблоне класса с помощью ifsteam - PullRequest
0 голосов
/ 22 марта 2019

По какой-то причине я не могу найти правильный знак функции шаблона, чтобы перегрузить мой шаблон класса Arr с помощью ifstream ... (ofstream работал) Мне очень трудно понять это ...

Вот мой код:

#include <iostream>
using namespace std;
#include <fstream>

template<typename T, int N = 1>
class Arr {
    T m_data[N];
public:
    Arr(const T& initializer = 0) {   //only for context
        for (int i = 0; i < N; i++)
            m_data[i] = initializer;
    };
    Arr(initializer_list<T> values) {   //only for context
        copy(values.begin(), values.end(), m_data);
    };
    ~Arr() {};                        //only for context

    T operator[](unsigned index) const {   //only for context
        return m_data[index];
    }
    T& operator[](int index) {   //only for context
        return m_data[index];
    };
};

template <typename T, int N>        //OK
ostream& operator<<(ostream &os, const Arr<T, N>& v)
{
    for (int i = 0; i < N; i++)
        os << v[i] << ' ';
    return os;
}

template<typename T, int N>       //OK
ofstream& operator<<(ofstream &os, const Arr<T, N>& v)
{
    int i;
    for (i = 0; i < N - 1; i++)
        os << v[i] << ',';
    os << v[i];
    return os;
}

template<typename T, int N>     // NEVER REACHING HERE
T operator>>(ifstream &os, T v)
{
     //not reading
}

template<typename T, int N>     //OK
ifstream& operator>>(ifstream &os, const Arr<T, N>& v)
{
    for (int i = 0; i < N; i++)
        os >> v[i];     //C2679 binary '>>': no operator found which takes a right-hand operand of type 'T' (or there is no acceptable conversion)
    return os;
}



int main()
{
    Arr<float, 9> numbers({ 1,2,3,4,5,6,7,8,9 });
    cout << numbers;             // ok
    ofstream outf;
    outf.open("myStat.csv");
    outf << numbers;             // OK(save numbers to file)
    outf.close();
    Arr<float, 9> numbers_load;
    ifstream inf;
    inf.open("myStat.csv");

    inf >> numbers_load;      // the problem here(explanation below)

}

Примечание: numbers_load равно Arr<T, N>, поэтому inf >> loaded_players будет звонить на
ifstream& operator>>ifstream &os, const Arr<T, N>& v), нотогда произойдет ошибка, потому что компилятор не может найти T operator>>(ifstream &os, T v).Почему?

Буду очень признателен за любую помощь.

1 Ответ

1 голос
/ 22 марта 2019

В вашей функции

template<typename T, int N>
T operator>>(ifstream &os, T v);

нет способа вывести значение для параметра шаблона N.(Это работает для других функций, принимающих параметр const Arr<T,N>&, потому что компилятор может сравнить этот тип параметра с типом аргумента, таким как Arr<float, 9> и определить, что T равно float, а N равно 9.)

Таким образом, вы можете удалить шаблонный параметр int N ... но это действительно плохая идея - определить шаблонную функцию, которая говорит, как вообще получить любой тип объекта из ifstream.Многие встроенные типы, стандартные типы библиотек и пользовательские типы определяют свои собственные версии operator>>, в которых говорится, как получить их из std::istream или, в более общем случае, из std::basic_istream<CharT, CharTraits>.И добавление этой перегрузки даст некоторые неочевидные результаты о том, использует ли какой-либо конкретный токен >> существующие определения или ваш новый.И существующий код, который предполагает использование обычного operator>>, может внезапно переключиться на использование вашего.

Если вы просто хотите, чтобы место, чтобы определить, что делать с каждым элементом при вводе в Arr<T,N>, определитефункция с обычным именем для этого, а не operator>>.

(Менее сломанное, но все еще нестабильное дизайнерское решение, это та часть, где os << some_arr; делает разные вещи в зависимости от того, статический тип os это std::ifstream или нет. Это по крайней мере необычно. И обратите внимание, что это может привести к ситуациям, когда кто-то передает std::ofstream в функцию, принимающую std::ostream&, так что внутри этой функции << означает не-файл версии, даже если объект потока на самом деле является ifstream.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...