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

overloading << in class template with ifsteam

本文关键字:lt ifSteam 重载 使用      更新时间:2023-10-16

由于某种原因,我找不到正确的模板函数符号来重载我的类模板 Arr 与 ifstream...(流工作) 我真的很难弄清楚这一点...

这是我的代码:

#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)。为什么?

任何帮助将不胜感激。

在你的函数中

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

无法推断模板参数N的值。 (它适用于采用const Arr<T,N>&参数的其他函数,因为编译器可以将该参数类型与Arr<float, 9>等参数类型进行比较,并推断TfloatN9

因此,您也许可以删除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