我正在尝试读取二进制数据以将结构加载回内存,以便我可以编辑它们并将它们保存回.dat文件。
readVector()尝试读取文件,并返回序列化的向量。但是当我尝试运行它时,我收到了这个编译错误。我的模板出了什么问题?
*********编辑******************
代码:
// Project 5.cpp : main project file.
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
using namespace System;
using namespace std;
#pragma hdrstop
int checkCommand (string line);
template<typename T>
void writeVector(ofstream &out, const vector<T> &vec);
template<typename T>
vector<T> readVector(ifstream &in);
struct InventoryItem {
string Item;
string Description;
int Quantity;
int wholesaleCost;
int retailCost;
int dateAdded;
} ;
int main(void)
{
cout << "Welcome to the Inventory Manager extreme! [Version 1.0]" << endl;
ifstream in("data.dat");
vector<InventoryItem> structList;
readVector<InventoryItem>( in );
while (1)
{
string line = "";
cout << endl;
cout << "Commands: " << endl;
cout << "1: Add a new record " << endl;
cout << "2: Display a record " << endl;
cout << "3: Edit a current record " << endl;
cout << "4: Exit the program " << endl;
cout << endl;
cout << "Enter a command 1-4: ";
getline(cin , line);
int rValue = checkCommand(line);
if (rValue == 1)
{
cout << "You've entered a invalid command! Try Again." << endl;
} else if (rValue == 2){
cout << "Error calling command!" << endl;
} else if (!rValue) {
break;
}
}
system("pause");
return 0;
}
int checkCommand (string line)
{
int intReturn = atoi(line.c_str());
int status = 3;
switch (intReturn)
{
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
status = 0;
break;
default:
status = 1;
break;
}
return status;
}
template<typename T>
void writeVector(ofstream &out, const vector<T> &vec)
{
out << vec.size();
for(vector<T>::const_iterator i = vec.begin(); i != vec.end(); i++)
{
out << *i;
}
}
ostream& operator<<(std::ostream &strm, const InventoryItem &i) {
return strm << i.Item << " (" << i.Description << ")";
}
template<typename T>
vector<T> readVector(ifstream &in)
{
size_t size;
in >> size;
vector<T> vec;
vec.reserve(size);
for(int i = 0; i < size; i++)
{
T tmp;
in >> tmp;
vec.push_back(tmp);
}
return vec;
}
编译器错误:
1>------ Build started: Project: Project 5, Configuration: Debug Win32 ------
1>Compiling...
1>Project 5.cpp
1>.\Project 5.cpp(124) : warning C4018: '<' : signed/unsigned mismatch
1> .\Project 5.cpp(40) : see reference to function template instantiation 'std::vector<_Ty> readVector<InventoryItem>(std::ifstream &)' being compiled
1> with
1> [
1> _Ty=InventoryItem
1> ]
1>.\Project 5.cpp(127) : error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'InventoryItem' (or there is no acceptable conversion)
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(1144): could be 'std::basic_istream<_Elem,_Traits> &std::operator >><std::char_traits<char>>(std::basic_istream<_Elem,_Traits> &,signed char *)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(1146): or 'std::basic_istream<_Elem,_Traits> &std::operator >><std::char_traits<char>>(std::basic_istream<_Elem,_Traits> &,signed char &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(1148): or 'std::basic_istream<_Elem,_Traits> &std::operator >><std::char_traits<char>>(std::basic_istream<_Elem,_Traits> &,unsigned char *)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(1150): or 'std::basic_istream<_Elem,_Traits> &std::operator >><std::char_traits<char>>(std::basic_istream<_Elem,_Traits> &,unsigned char &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(155): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(std::basic_istream<_Elem,_Traits> &(__cdecl *)(std::basic_istream<_Elem,_Traits> &))'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(161): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(std::basic_ios<_Elem,_Traits> &(__cdecl *)(std::basic_ios<_Elem,_Traits> &))'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(168): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(std::ios_base &(__cdecl *)(std::ios_base &))'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(175): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(std::_Bool &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(194): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(short &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(228): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(unsigned short &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(247): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(int &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(273): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(unsigned int &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(291): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(long &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(309): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(__w64 unsigned long &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(329): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(__int64 &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(348): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(unsigned __int64 &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(367): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(float &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(386): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(double &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(404): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(long double &)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(422): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(void *&)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\istream(441): or 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::operator >>(std::basic_streambuf<_Elem,_Traits> *)'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> while trying to match the argument list '(std::ifstream, InventoryItem)'
1>Build log was saved at "file://c:\Users\Owner\Documents\Visual Studio 2008\Projects\Project 5\Project 5\Debug\BuildLog.htm"
1>Project 5 - 1 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
噢,我的上帝......我想到了我认为的那个错误,现在又得到了另一个错误。请你帮我解决这个问题吧!这到底是什么意思??
答案 0 :(得分:6)
readVector( in ); // error C2783
这应该是:
readVector<InventoryItem>( in );
依赖于参数的查找无助于推断模板,因此需要明确的规范。
in >> tmp;
此行要求您具有以下功能:
istream& operator>>(ostream& is, InventoryItem& item) {
// parse and read in the data to item
return is;
}
加入定义(我认为strager在你的另一个问题中提供了这个)。
答案 1 :(得分:2)
当你调用readVector时,通常会尝试从参数中推断出模板参数。
在您的示例中,唯一模板化的部分是返回值,因此无法隐式地计算出来。
改变你的电话
readVector(in)
到
vector<InventoryItem> structList = readVector<InventoryItem>(in);
答案 2 :(得分:2)
我认为正在发生的事情是,ofstream不知道如何序列化你的结构。
您可能需要定义&gt;&gt;和&lt;&lt; InventoryItem的运算符:
ofstream& operator << ( ofstream& ofs, InventoryItem& );
ifstream& operator >> ( ifstream& ifs, InventoryItem& );
编辑::
这是一个完全有效的例子。在编辑之前,我在ifstream上的工作很少。
#include < iostream >
#include < fstream >
#include < string >
struct InventoryItem{
std::string name;
int id;
float price;
};
using std::ofstream;
using std::ifstream;
ofstream& operator << (ofstream& ofs, InventoryItem& ii)
{
ofs << ii.name << std::endl
<< ii.id << std::endl
<< ii.price << std::endl;
return ofs;
}
ifstream& operator >> ( ifstream& ifs, InventoryItem& ii )
{
ifs >> ii.name >> ii.id >> ii.price;
return ifs;
}
void printItem(const InventoryItem& ii)
{
std::cout << "Name: " << ii.name << std::endl
<< "ID: " << ii.id << std::endl
<< "Price: " << ii.price << std::endl;
}
int main()
{
ofstream outfile("testout.txt");
InventoryItem list[] = { {"Item1", 1, 1.5}, {"Item2", 2, 2.5} };
outfile << list[0] << list[1];
outfile.close();
std::ifstream infile("testout.txt");
InventoryItem list2[2];
infile >> list[0] >> list[1];
printItem(list[0]);
printItem(list[1]);
return 0;
}
#include < iostream >
#include < fstream >
#include < string >
struct InventoryItem{
std::string name;
int id;
float price;
};
using std::ofstream;
using std::ifstream;
ofstream& operator << (ofstream& ofs, InventoryItem& ii)
{
ofs << ii.name << std::endl
<< ii.id << std::endl
<< ii.price << std::endl;
return ofs;
}
ifstream& operator >> ( ifstream& ifs, InventoryItem& ii )
{
ifs >> ii.name >> ii.id >> ii.price;
return ifs;
}
void printItem(const InventoryItem& ii)
{
std::cout << "Name: " << ii.name << std::endl
<< "ID: " << ii.id << std::endl
<< "Price: " << ii.price << std::endl;
}
int main()
{
ofstream outfile("testout.txt");
InventoryItem list[] = { {"Item1", 1, 1.5}, {"Item2", 2, 2.5} };
outfile << list[0] << list[1];
outfile.close();
std::ifstream infile("testout.txt");
InventoryItem list2[2];
infile >> list[0] >> list[1];
printItem(list[0]);
printItem(list[1]);
return 0;
}
预期输出为:
Name: Item1 ID: 1 Price: 1.5 Name: Item2 ID: 2 Price: 2.5
答案 3 :(得分:0)
当编译器无法解析模板参数的类型时,会发生此错误。
以下是我的代码中的示例:
template QSP<VarDataInterface<qint64>> VarDataManager::interpolateFromDB(
const DBWrapper & _db, const QString &variablePath, const QString &_unit,
const DBWrapper * _dbRef /*= nullptr*/,
const QString &refPath /*= QString::null*/,
const QString &_unitRef /*= QString::null*/ );
template QSP<VarDataInterface<QString>> VarDataManager::interpolateFromDB(
const TA5::IDBWrapper & _db, const QString &variablePath,
const QString &_unit, const TA5::IDBWrapper * _dbRef /*= nullptr*/,
const QString &refPath /*= QString::null*/, const QString &_unitRef /*= QString::null*/ );
template< class TYPE >
QSP<VarDataInterface<TYPE>> VarDataManager::interpolateFromDB(
const DBWrapper & _db, const QString &variablePath, const QString &_unit,
const DBWrapper * _dbRef /*= nullptr*/,
const QString &refPath /*= QString::null*/,
const QString &_unitRef /*= QString::null*/ )
{
const Header dbVar = _db.getDatabaseVariable( variablePath );
if( !dbVar.isValid() )
return QSP<VarDataInterface<TYPE>>(nullptr);
TVariableHeader dbVarRef;
if( _dbRef != nullptr )
{
//
}
else
{
//
}
return QSP<VarDataInterface<TYPE>>();
}
在这里使用:
我第一次尝试写这个
m_Var = VarDataManager::interpolateFromDB(VarDataManager::getMainDB(), treeitem->text(0), QString::null, nullptr, QString::null, QString::null);
并得到错误C2783。解决了这个
m_Var = VarDataManager::interpolateFromDB<double>(VarDataManager::getMainDB(), treeitem->text(0), QString::null, nullptr, QString::null, QString::null);
HTH