Не существует подходящей функции преобразования из "const std::string" в "double"
Всем привет,столкнулся с такой проблемой "Не существует подходящей функции преобразования из "const std::string" в "double"" в строчке 52.Как ее решить?И извините за плохо вставленный код,еще не научился правильно вставлять коды в этом сайте.
#include <iostream>
#include <string>
#include <fstream>
#include <algorithm>
using namespace std;
class Contingent {
protected:
string firstname, lastname;
int age;
public:
Contingent(string = "John", string = "Jones", int = 32);
~Contingent() = default;
void printClass()const;
};
class HeightSchool {
protected:
string name;
int departments;
public:
HeightSchool(string = "Brighton", int = 5);
~HeightSchool() = default;
void printClass()const;
double getPub()const;
};
class Bachelor :public Contingent, public HeightSchool {
string specialty;
int grade;
public:
Bachelor(string = "Chemist", int = 51);
~Bachelor() = default;
bool operator <(const Bachelor&);
friend istream& operator >>(istream&, Bachelor&);
friend ostream& operator <<(ostream&, const Bachelor&);
};
Contingent::Contingent(string f, string l, int a) :
firstname(f), lastname(l), age(a) {}
void Contingent::printClass()const {
cout << "Saxeli: " << firstname
<< "\nGvari: " << lastname
<< "\nAsaki: " << age << endl;
}
HeightSchool::HeightSchool(string n, int d) :
name(n), departments(d) {}
void HeightSchool::printClass()const {
cout << "Dasaxeleba: " << name
<< "\nFakultetebis ricxvi: " << departments << endl;
}
double HeightSchool::getPub()const { return name; }
Bachelor::Bachelor(string s, int g) :
Contingent(), HeightSchool(), specialty(s), grade(g) {}
bool Bachelor::operator <(const Bachelor& l) {
return this->grade < l.grade;
}
istream& operator >>(istream& in, Bachelor& l) {
return in >> l.firstname >> l.lastname
>> l.age >> l.name >> l.departments
>> l.specialty >> l.grade;
}
ostream& operator <<(ostream& out, const Bachelor& l) {
return out << "Saxeli: " << l.firstname
<< "\nGvari: " << l.lastname
<< "\nAsaki: " << l.age
<< "\nDasaxeleba: " << l.name
<< "\nFakultetebis ricxvi: " << l.departments
<< "\nSpecialoba: " << l.specialty
<< "\nShefaseba: " << l.grade << endl;
}
void fillArray(Bachelor*, int&);
void printArray(const Bachelor*, int&);
void intoFile(const Bachelor*, int&);
int main() {
static Contingent C("Dustin", "Poirier", 32);
C.printClass();
cout << "--------------------" << endl;
static HeightSchool H("Tonbridge", 4);
H.printClass();
cout << "--------------------" << endl;
Bachelor* ptr = new(nothrow) Bachelor[1200];
int realSize{ 0 };
fillArray(ptr, realSize);
sort(ptr, ptr + realSize, [](Bachelor& k, Bachelor& l) { return l < k; });
printArray(ptr, realSize);
intoFile(ptr, realSize);
delete[] ptr;
ptr = nullptr;
}
void fillArray(Bachelor* arr, int& n) {
ifstream ifs("bachelor.txt");
while (!ifs.eof()) {
ifs >> arr[n++];
}
ifs.close();
}
void printArray(const Bachelor* arr, int& n) {
for (int i = 0; i < n; ++i) {
cout << arr[i];
cout << "--------------------" << endl;
}
}
void intoFile(const Bachelor* arr, int& n) {
ofstream ofs("report.txt");
ofs << "Yvelaze udidesi shefaseba:\n\n";
for (int i = 0; i < n; ++i) {
ofs << arr[i];
if ((arr + i)->getPub() != (arr + i + 1)->getPub()) {
break;
}
}
ofs << "--------------------" << endl;
ofs << "Yvelaze umciresi shefaseba:\n\n";
for (int i = n - 1; i >= 0; ++i) {
ofs << arr[i];
if ((arr + n - i)->getPub() != (arr + n - i - 1)->getPub()) {
break;
}
}
ofs << "--------------------" << endl;
int average = 0;
for (int i = 0; i < n; ++i) {
average += (arr + i)->getPub();
}
average /= n;
int index = 0, dif = abs((arr)->getPub() - average);
for (int i = 1; i < n; ++i) {
if (abs((arr + i)->getPub() - average) < dif) {
index = i;
dif = abs((arr + i)->getPub() - average);
}
}
ofs << "Yvelaze axlos yvela bakalavris sashualo shefasebastan:\n\n";
ofs << arr[index];
ofs << "--------------------" << endl;
ofs.close();
}
Ответы (2 шт):
double HeightSchool::getPub()const { return name; }
Что такое name? Строка. Вы возвращаете строку, но требуете, чтобы было возвращено значение типа double. Вам ничего не кажется странным?
Можно, конечно, так:
double HeightSchool::getPub()const { return stod(name); }
Это скомпилируется... Но есть ли хоть какая-то гарантия, что в name будет именно строковое представление числа double? Может, стоит пересмотреть свой проект?
Да, еще потом у вас
int average = 0;
...
average += (arr + i)->getPub();
т.е. вы еще и это преобразованное в double значение дополнительно преобразуете в int. Ой, неладно что-то в датском королевстве...
Я не буду даже пытаться разобраться в вашем коде, но за правильное переобразование типа данных отвечает static_cast
//...
int n = 45;
double d = static_cast<double>(n);
std::cout << a << ", " << d;
//...
В консоли выведется: 45, 45.0
Но для прямого преобразования string в double static_cast не сработает
Поэтому вы можете воспользоваться моим кодом, который я писал для себя ради интереса
// проверяет строку на то, что ее содержимое сможет
// сконвертироваться в double
bool doubleSigned(const std::string& s)
{
size_t offset=0;
if(s[offset]=='-')
++offset;
return s.find_first_not_of("0123456789.,", offset) == std::string::npos;
}
double in_double(std::string &str)
{
// если можно сконвертировать
if (doubleSigned(str))
{
int factor, sign, symbol, value = 0;
// вычисляем знак числа (+/-)
if (static_cast<int>(str.at(0)) == 45)
{
factor = -1;
sign = 0;
}
else
{
factor = 1;
sign = -1;
}
int counter = 0;
int point = 0;
// конвертируем
for (int i = str.size() - 1; i > sign; i--)
{
// берем номер символа
symbol = static_cast<int>(str.at(i));
// если символ = "." или "," то устанавливаем ее
// позицию
if (symbol == 44 || symbol == 46)
{
if (point == 0)
{
int power = 0;
point = 1;
while (power < counter)
{
point *= 10;
power++;
}
counter++;
}
continue;
}
// записываем символ в число
value += (static_cast<int>(str.at(i)) - 48) * factor;
factor *= 10;
counter++;
}
// конвертируем полученное чисоло в double
// вставляем точку на ее законное место
double d = static_cast<double>(value) / static_cast<double>(point);
return d;
}
// в качестве возвращаемого значения предлагаю
// возвращать указатель, а не так как тут, чтоб
// в случае неудачной конвертации возвращался
// nullptr
else
return -1.0;
}
Я не знаю, как оценят код специалисты, но он работает. Я соглашусь, если в нем много всего лишнего, но не судите строго, я тоже новичок.