I am studying C++ on Essential C++ by lippman. Here is some code where two lines contain error while I don't know why it's happening and how to fix it.
#include "stdafx.h"
#include <vector>
#include <iostream>
#include <cstdlib>
#include <fstream>
using namespace std;
const vector<int>* fibon_seq(int size) {
const int max_size = 1024;
static vector<int> elems;
if (size <= 0 || size > max_size) {
cerr << "Error";
return 0;
}
for (int ix = elems.size(); ix < size; ++ix) {
if (ix == 0 || ix == 1)
elems.push_back(1);
else elems.push_back(elems[ix - 1] + elems[ix - 2]);
}
return &elems;
}
void display(const vector<int>* vec, ostream &os = cout) {
if (!vec)
cerr << "null vector";
for (int i = 0; i < (vec)->size(); ++i)
os << (*vec)[i] << " ";
os << endl;
}
bool fibon_elem(int pos, int &elem, const vector<int>* (*seq_ptr)(int)) {
const vector<int> *pseq = seq_ptr(pos);
if (!pseq){
elem = 0; return false;
}
elem = (*pseq)[pos - 1];
return true;
}
int main()
{
const vector<int>* (*(*seq_array)[1])(int);
(*seq_array)[0] = fibon_seq;
vector<int>* (*seq_ptr)(int);
int seq_index = 0;
seq_ptr = (*seq_array)[0];//This is the line with error.
//(a value of type "const std::vector<int, std::allocator<int>> *(*)(int)"
//cannot be assigned to an entity of type "std::vector<int, std::allocator<int>>
//*(*)(int)"
//C2440 '=': cannot convert from 'const std::vector<int,std::allocator<_Ty>>
//*(__cdecl *)(int)' to 'std::vector<int,std::allocator<_Ty>>
//*(__cdecl *)(int)'
int a;
fibon_elem(12, a, seq_ptr);//This is the line with error.
//argument of type "std::vector<int, std::allocator<int>> *(*)(int)"
//is incompatible with parameter of type "const std::vector<int, std::allocator<int>>
//*(*)(int)"
//C2664 'bool fibon_elem(int,int &,const std::vector<int,std::allocator<_Ty>>
//*(__cdecl *)(int))': cannot convert argument 3 from 'std::vector<int,std::allocator<_Ty>>
//*(__cdecl *)(int)' to 'const std::vector<int,std::allocator<_Ty>>
//*(__cdecl *)(int)' test
getchar();
return 0;
}
For the first line in error, I make both sides of the equation the same type, while the compiler says that the value cannot be assigned. For the second line in error, the two same type are incompatible with each other.
And the error message given by compiler is the following:
Your function fibon_seq returns a const vector<int>*, and you're trying to assign it to a vector<int>* which is seq_ptr. Change seq_ptr to a const vector<int>* or change the return type of fiber_seq.
Related
I'm just revisiting C++, and I have a question about overloading of the [] operator, and more specifically why my program doesn't work.
Given the following code in vec.cpp:
double Vec::operator[](unsigned int i) const {
return this->values[i];
}
double & Vec::operator[](unsigned int i) {
return this->values[i];
}
These are defined in vec.h as methods to the Vec class, and if I do not use the operator in my main.cpp, all is fine and dandy. It compiles just as normal with no errors.
However once I do this in my main function (which is using std::cout and std::endl):
cout << a[0] << endl;
Things go wrong. The errors I get are a bunch of
candidate function template not viable: no known conversion from 'Vec' to 'char' for 2nd argument
operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn)
where you can replace 'char' with any primitive data type.
Here is a working example
// In vec.h
#pragma once
#include <string>
#include <iostream>
class Vec {
private:
int dims;
double *values;
public:
Vec(int dims, double values[]);
double operator [](unsigned int i) const;
double& operator[](unsigned int i);
};
// In vec.cpp
#include <iostream>
#include <string>
#include <cmath>
#include "vec.h"
using std::cerr, std::endl, std::cout;
Vec::Vec(int dims, double values[]) {
this->dims = dims;
this->values = new double[dims];
for(int i = 0; i < dims; i++) {
this->values[i] = values[i];
}
}
double Vec::operator[](unsigned int i) const {
if(i >= this->dims) {
cerr << "Elem out of range" << endl;
}
return this->values[i];
}
double & Vec::operator[](unsigned int i) {
if(i >= this->dims) {
cerr << "Elem out of range" << endl;
}
return this->values[i];
}
// In main.cpp
#include <iostream>
#include <string>
#include "vec.h"
using std::cout, std::endl;
int main() {
double avals[2];
avals[0] = 1.0;
avals[1] = 2.0;
Vec *a = new Vec(2, avals);
cout << a[0] << endl; // Error occurs here
return 0;
}
Can anyone help me sort this out?
In this declaration
Vec *a = new Vec(2, avals);
there is declared a pointer of the type Vec *. So an expression with the dereferenced pointer has the type Vec.
So in this statement
cout << a[0] << endl;
the expression a[0] has the type Vec.
It seems you mean
( *a )[0]
or
a[0][0]
#include <iostream>
#include <limits>
#include <string>
using namespace std;
void wczytajOsobe(string imie[], string nazwisko[], int wiek[])
{
int i=2;
for(int indeks=0;i>indeks;indeks++)
{
cout << "Podaj Imie: " << endl;
getline(cin, imie[indeks]);
cout << "Podaj Naziwsko: " << endl;
getline(cin, nazwisko[indeks]);
}
}
void wypiszOsobe(string imie[], string nazwisko[], int wiek[])
{
int i=2;
for(int indeks=0;i>indeks;indeks++)
{
cout << imie[indeks];
cout << nazwisko[indeks];
cout << wiek[indeks];
}
}
int main()
{
string imie[2];
string nazwisko[2];
int wiek[2];
for( int i = 0; i < 2; i++ )
wczytajOsobe(imie[i], nazwisko[i], wiek[i]);
for( int i = 0; i < 2; i++ )
wypiszOsobe(imie[ i ], nazwisko[ i ], wiek[ i ] );
system("PAUSE");
return 0;
}
This is my code and i have problem with|36|error: cannot convert 'std::__cxx11::string {aka std::__cxx11::basic_string}' to 'std::__cxx11::string* {aka std::__cxx11::basic_string}' for argument '1' to 'void wczytajOsobe(std::__cxx11::string, std::__cxx11::string*, int*)'|
can somebody help me with that issue ?
You have two functions defined as:
void wczytajOsobe(string imie[], string nazwisko[], int wiek[]);
void wypiszOsobe(string imie[], string nazwisko[], int wiek[]);
Because arrays decay to pointers when passed to functions, the parameter types are actually:
void wczytajOsobe(string *imie, string *nazwisko, int *wiek);
void wypiszOsobe(string *imie, string *nazwisko, int *wiek);
When you call the functions like:
for( int i = 0; i < 2; i++ )
wczytajOsobe(imie[i], nazwisko[i], wiek[i]);
You're not passing arrays but individual array elements. That's why the error message says it can't convert std::string to std::string*.
You don't need those loops in main(). You can just call the functions as:
int main()
{
string imie[2];
string nazwisko[2];
int wiek[2];
wczytajOsobe(imie, nazwisko, wiek);
wypiszOsobe(imie, nazwisko, wiek);
system("PAUSE");
return 0;
}
Note that I'm just passing the arrays to the functions.
I am trying to implement own set in C++ using class templates and operators overriding.
I have following code in my MySet.h file:
#include "stdafx.h"
#pragma once
#include <iostream>
#include <string>
using namespace std;
#define DEFAULT_LEN 10
template <class T> class MySet
{
public:
MySet(int len = DEFAULT_LEN)
{
elements = new T[len];
count = 0;
}
~MySet()
{
delete elements;
}
MySet<T> operator+(T &element)
{
cout << "Some code here!"; //deleted to simplify code, the problem is that this method is not seen in main
return MySet<T>();
}
string writeSet()
{
string result = "";
for (int i = 0;i < count; i++)
{
result += elements[i] + ", ";
}
return result;
}
private:
T* elements;
int count;
};
and this in my main:
#include "stdafx.h"
#include "MySet.h"
int main()
{
MySet<int> a = MySet<int>(10);
cout << a.writeSet();
a = a + 2;
a = a + 3;
a = a + 4;
cout << a.writeSet();
return 0;
}
Unfortunately I am getting problems while compilling with this lines:
a = a + 2;
. The output is:
1>c:\path\main.cpp(11): error C2679: binary '+': no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)
1> c:\path\myset.h(22): note: could be 'MySet<int> MySet<int>::operator +(T &)'
1> with
1> [
1> T=int
1> ]
How is this possible? As far as I understand it, MySet<T> operator+(T &element) should be enough because of T type. What am I missing?
It has to be:
MySet<T> operator+(const T &element)
I have been trying to implement Stack that holds objects of MyString class (it is exercise from one of the books). I managed to push those objects to container, but when I want to call function void print() I get an error:
error: passing 'const MyString' as 'this' argument of 'void MyString::print()' discards qualifiers [-fpermissive]
cp->print();
Here is the code:
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
class MyString
{
string a;
public:
MyString(string aa) : a(aa)
{
}
void print()
{
cout << a << endl;
}
};
class StringStack {
static const int size = 100;
const MyString* stack[size];
int index;
public:
StringStack();
void push(const MyString* s); // does this have to be const?
const MyString* pop(); // does this have to be const?
};
StringStack::StringStack() : index(0) {
memset(stack, 0, size * sizeof(MyString*));
}
void StringStack::push(const MyString* s) {
if(index < size)
stack[index++] = s;
}
const MyString* StringStack::pop() {
if(index > 0) {
const MyString* rv = stack[--index];
stack[index] = 0;
return rv;
}
return 0;
}
MyString s0("pralines & cream");
MyString s1("fudge ripple");
MyString s2("jamocha almond fudge");
MyString s3("wild mountain blackberry");
MyString s4("raspberry sorbet");
MyString s5("lemon swirl");
MyString s6("rocky road");
MyString s7("deep chocolate fudge");
MyString iceCream[] = {s0,s1,s2,s3,s4,s5,s6,s7};
const int iCsz =
sizeof iceCream / sizeof *iceCream;
int main() {
StringStack ss;
for(int i = 0; i < iCsz; i++)
ss.push(&iceCream[i]);
const MyString* cp;
while((cp = ss.pop()) != 0)
{
cout << (long)cp << endl;
// cp->print(); // won't work
}
} ///:~
You can either:
make void MyString::print() const, which seems to be reasonable.
or :
make const MyString* pop(); to return non const pointers.
I dont think that StringStack should store pointers to const objects. If you plan to never modify MyString objects from your stack, then keep them internally as const. The choice depends on your requirements.
Im trying to sort an array of objects by one of their attributes using c++ STL sort() but I always get an error:
main.cpp: In function 'bool sortByArea(const Shape*, const Shape*)':
main.cpp:54:22: error: passing 'const Shape' as 'this' argument of 'double Shape::getArea()' discards qualifiers [-fpermissive]
return lhs->getArea() < rhs->getArea();
^
main.cpp:54:39: error: passing 'const Shape' as 'this' argument of 'double Shape::getArea()' discards qualifiers [-fpermissive]
return lhs->getArea() < rhs->getArea();
Here is my code:
Shape.cpp
#include "Shape.h"
Shape::Shape(){
width=0;
height=0;
area=0;
perimeter=0;
}
Shape::Shape(double newwidth, double newheight, double newarea, double newperimeter){
width=newwidth;
height=newheight;
area=newarea;
perimeter=newperimeter;
}
Shape::~Shape(){
}
double Shape::getWidth(){
return width;
}
double Shape::getHeight(){
return height;
}
double Shape::getArea(){
return area;
}
double Shape::getPerimeter(){
return perimeter;
}
double Shape::calArea(){
return 0;
}
double Shape::calPerimeter(){
return 0;
}
Circle.cpp
#include "Circle.h"
#include <cmath>
#define PI 3.141592654
Circle::Circle(){
width = height = 0;
area=0; perimeter=0;
}
Circle::Circle(double newradius){
width = height = newradius;
area = calArea(); perimeter = calPerimeter();
}
Circle::~Circle(){
}
double Circle::calArea(){
return (pow(width,2)*PI);
}
double Circle::calPerimeter(){
return (width * PI * 2);
}
main.cpp
#include "Shape.h"
#include "Circle.h"
#include "Rectangle.h"
#include "Square.h"
#include <fstream>
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int size = 200;
int cshape = 0; int rshape = 0; int sshape = 0;
void input_circle(Shape* mshape){
ifstream file;
int i;
double r;
file.open("circle.txt");
while (file >> r){
Circle crl(r);
mshape[cshape]=crl;
cshape++;
}
file.close();
}
bool sortByArea(const Shape * lhs, const Shape * rhs) {
return lhs->getArea() < rhs->getArea();
}
int main(){
Shape* shapecir;
shapecir = new (nothrow) Circle[size]();
input_circle(shapecir);
int i;
cout << "Circle" << endl;
sort(shapecir,shapecir+size,sortByArea);
for (i=0;i<cshape;i++)
cout << shapecir[i].getArea() << " " << shapecir[i].getPerimeter() << endl;
return 0;
}
I tried to find something on the internet but I can't find anything that can help.
You ought to have tested these functions as you wrote them. The problem is here:
double Shape::getArea(){
return area;
}
bool sortByArea(const Shape * lhs, const Shape * rhs) {
return lhs->getArea() < rhs->getArea();
}
You correctly gave sortByArea const pointer arguments, but neglected to make getArea a const function. The compiler is telling you that you are commanding that the code perform an operation that might change the shapes, after you forbade that they be changed.