簡體   English   中英

模板C ++錯誤:無法推斷出模板參數

[英]Templates C++ error : could not deduce template argument

我正在嘗試添加一個功能模板,如果該模板包含精度值或閥門以及該值,則將進行打印。 除此功能外,程序的其余部分均有效。 我不確定自己在做什么錯,但是我收到的錯誤是:

錯誤C2784:'void printInstrumentDetail(const I * const)':無法從'std :: vector <_Ty>'推導出'const I * const'的模板參數

#include <iostream>
#include <vector>
#include <iomanip>
#include <string>
#include "Instruments.h"
#include "Brass.h"
#include "Strings.h"

using namespace std;

//template<typename I>                    <---Problem
//void printInstrumentDetail(const I * const a)
//{
//      for (size_t i = 0; i < 6; i ++)
//  {
//      cout << "The details for " << a[i]->getName()
//          << ": " << a[i]->print();
//  }
//}
int main()
{
    double total = 0;

    Strings violin("Violin", 553.90, 3);
    Strings cello("Cello", 876.45, 3);
    Strings viola("Viola", 200.50, 23);
    Brass tuba("Tuba", 1400.10, 1.23);
    Brass trumpet("Trumpet", 500.00, 4.32);
    Brass sax("Sax", 674.78, .99);

    vector <Instruments *> band(6);

    band[0] = &violin;
    band[1] = &tuba;
    band[2] = &cello;
    band[3] = &trumpet;
    band[4] = &viola;
    band[5] = &sax;

    cout << fixed << setprecision(2);

    cout << "The instruments in the band are:\n";
    //Get name and cost of each
    for (size_t i = 0; i < 6; i ++)
    {
        cout << band[i]->getName() << "     $" 
            << band[i]->getCost() << endl;
    }

    cout << "\nThen band is warming up..." << endl;
    //Get descrition of how sound is made of each
    for (size_t i = 0; i < 6; i ++)
    {
        cout << "This " << band[i]->getName()
            << " makes sounds by " ;
        band[i]->playSound();
    }
    cout << "\nTotal cost of the band is: $" ;
    //Get total cost of all instruments
    for (size_t i = 0; i < 6; i ++)
    {

        total = band[i]->getCost() + total;
    }
    cout << total << endl;

    //printInstrumentDetail(band);                     <--Problem

    return 0;
}

這是基類:

#ifndef INSTRUMENTS_H
#define INSTRUMENTS_H

#include <string>

using namespace std;

class Instruments
{
public:
    Instruments(string, double);

    void setName(string);
    virtual string getName();

    void setCost(double);
    virtual double getCost();

    virtual void print();

    virtual void playSound();

private:
    string name;
    double cost;
};
#endif

#include <iostream>
#include "Instruments.h"

using namespace std;

Instruments::Instruments(string n, double c)
{
    name = n;
    cost = c;
}
void Instruments::setName(string n)
{
    name = n;
}
string Instruments::getName()
{
    return name;
}
void Instruments::setCost(double c)
{
    cost = c;
}
double Instruments::getCost()
{
    return cost;
}
void Instruments::print() 
{

}
void Instruments::playSound()
{
    //empty
}

派生類低音:

#ifndef BRASS_H
#define BRASS_H

#include <string>
#include "Instruments.h"

using namespace std;

class Brass : public Instruments
{
public:
    Brass(string, double, double);

    void setPrecisionValue(double);
    double getPrecisionValue();
    void print() ;
     void playSound();

private:
    double precision;
    string sound;
};
#endif

#include <iostream>
#include "Brass.h"

using namespace std;

Brass::Brass(string n, double c, double p)
:Instruments(n, c)
{
    precision = p;
}
void Brass::setPrecisionValue(double p)
{
    precision = p;
}
double Brass::getPrecisionValue()
{
    return precision;
}
void Brass::print() 
{
    cout << getPrecisionValue() << endl;
}
void Brass::playSound()
{
    cout << "blowing in a mouthpiece." << endl;
    Instruments::playSound();
}

派生類字符串:

#ifndef STRINGS_H
#define STRINGS_H

#include <string>
#include "Instruments.h"

using namespace std;

class Strings : public Instruments
{
public:
    Strings(string, double, int);

    void setValves(int);
    int getValves();
    void print();
    void playSound();

private:
    int valves;
};
#endif

#include <iostream>
#include "Strings.h"

using namespace std;

Strings::Strings(string n, double c, int v)
    :Instruments(n, c)
{
    valves = v; 
}
void Strings::setValves(int v)
{
    valves = v;
}
int Strings::getValves()
{
    return valves;
}
void Strings::print() 
{
    cout<< getValves() << endl;
}
void Strings::playSound()
{
    cout << "striking with a bow." << endl;
    Instruments::playSound();
}

好吧,問題在於您的模板需要一個指針:

template<typename I>   
void printInstrumentDetail(const I * const a);

但您給它一個向量,而不是指針:

vector <Instruments *> band(6);
...
printInstrumentDetail(band);

您可以通過傳遞指向printInstrumentDetail函數的指針來解決此問題,如下所示:

printInstrumentDetail(&band[0]);

但實際上,最好將printInstrumentDetail修改為采用一個容器或一對迭代器:

template <typename ContainerT>   
void printInstrumentDetail(const ContainerT& a)

要么

template <typename IteratorT>
void printInstrumentDetail(IteratorT first, IteratorT last)

對功能的定義進行適當的修改。

將指針傳遞給vector

printInstrumentDetail(&band);   

和內部printInstrumentDetail

(*a)[i]->getName();

好吧,首先,我不相信您可以將向量作為const * I const傳遞給

printInstrumentDetail(band);

向量不能僅轉換為指針。 一種可行的解決方案是這樣的:


template <typename T>
void printInstrumentDetail( const std::vector<T*>& band )
{
    for ( size_t i = 0; i < band.size(); ++i )
        cout << "The details for " << band[i]->getName()
             << ": " << band[i]->print();
}

還有很多其他東西,包括迭代器,函子,STL算法等。

您正在嘗試將對象傳遞給需要指針的接口。

void printInstrumentDetail(const I * const a)

將此轉換為參考。

void printInstrumentDetail(I const I& a)

但是要符合C ++中常見的模式。 您應該將序列的開頭和結尾作為參數傳遞。 即更改您的函數以迭代器而不是指針。

而不是傳遞指針:

printInstrumentDetail(const I * const a)  

您可以傳遞參考:

printInstrumentDetail(const I& a)

其他所有內容保持不變。

首先,似乎根本沒有理由將PrintInstrumentDetail用作模板–它可以使用指向基類的指針,並且除非您可能具有其他類型的getName()print()成員,它可以被應用,它可以/應該/應該只使用指向基類的指針。

其次,我會認真考慮改變您的工作方式。 與其在每個Instrument中使用一個成員函數,以及在整個Instrument上循環使用PrintInstrumentDetail,我都想着要為Instrument定義operator<< ,並使用標准算法來打印出細節。

看看它,我認為其他一些事情也應該改變。 首先,除非您要處理的是非常不尋常的樂器,否則黃銅樂器上的閥門數量將永遠固定-因此,它不應具有SetValve()成員。 相反,應在施工期間設置閥門的數量,但以后不得打開以進行更改。

弦樂器根本沒有閥門(至少大多數普通的閥門沒有閥門),因此它們不應該具有SetValves()GetValves()或任何其他與閥門有關的東西。

同樣,除非您做一些非常不尋常的事情,否則儀器的成本永遠不會改變-您支付了所支付的費用,因此,應在施工期間確定成本,並且以后不得進行改動。

編輯:另一件事:使用band.size()循環遍歷band中的所有樂器,而不是在各處硬編碼6

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM