使用ifsteam重载类模板中的<<

时间:2019-03-21 23:31:22

标签: c++ templates operator-overloading

由于某种原因,我找不到正确的模板函数符号来将我的类模板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_loadArr<T, N>,因此inf >> loaded_players将呼叫
ifstream& operator>>ifstream &os, const Arr<T, N>& v),但由于编译器找不到T operator>>(ifstream &os, T v)会发生错误。为什么?

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

在您的职能中

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

无法推断出模板参数N的值。 (它适用于带有const Arr<T,N>&参数的其他函数,因为编译器可以将该参数类型与Arr<float, 9>这样的参数类型进行比较,并推论Tfloat和{ {1}}是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&表示非文件版本,甚至尽管流对象实际上是<<。)