编译错误C ++:无法推断'T'的模板参数

时间:2009-04-02 06:47:07

标签: c++ templates serialization compiler-errors

我正在尝试读取二进制数据以将结构加载回内存,以便我可以编辑它们并将它们保存回.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 ==========

噢,我的上帝......我想到了我认为的那个错误,现在又得到了另一个错误。请你帮我解决这个问题吧!这到底是什么意思??

4 个答案:

答案 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