由于某种原因,我找不到正确的模板函数符号来将我的类模板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)
会发生错误。为什么?
任何帮助将不胜感激。
答案 0 :(得分:1)
在您的职能中
template<typename T, int N>
T operator>>(ifstream &os, T v);
无法推断出模板参数N
的值。 (它适用于带有const Arr<T,N>&
参数的其他函数,因为编译器可以将该参数类型与Arr<float, 9>
这样的参数类型进行比较,并推论T
是float
和{ {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&
表示非文件版本,甚至尽管流对象实际上是<<
。)