Compilation error with struct/class defined in a function - c++

What is the problem with the following code. Because if I define the class inside the main function, the compilation fails and I don't understand the compiler error.
Test the code from here
Comment the 1st definition of drift_f (outside of main()) and uncomment the inner definition of drif_t (inside the main() function) and the compiler will get the following error message:
prog.cpp: In function ‘int main()’:
prog.cpp:27:24: error: template argument for ‘template<class> class std::allocator’ uses local type ‘main()::drift_t’
std::deque<drift_t> drift; drift.push_back(drift_t(0,0));drift.push_back(drift_t(-50,-50));
^
prog.cpp:27:24: error: trying to instantiate ‘template<class> class std::allocator’
prog.cpp:27:24: error: template argument 2 is invalid
prog.cpp:27:31: error: invalid type in declaration before ‘;’ token
std::deque<drift_t> drift; drift.push_back(drift_t(0,0));drift.push_back(drift_t(-50,-50));
^
prog.cpp:27:39: error: request for member ‘push_back’ in ‘drift’, which is of non-class type ‘int’
std::deque<drift_t> drift; drift.push_back(drift_t(0,0));drift.push_back(drift_t(-50,-50));
^
prog.cpp:27:69: error: request for member ‘push_back’ in ‘drift’, which is of non-class type ‘int’
std::deque<drift_t> drift; drift.push_back(drift_t(0,0));drift.push_back(drift_t(-50,-50));
#include <iostream>
#include <deque>
using namespace std;
class drift_t{ //It works
public:
int _drift;
int _immediateDrift;
drift_t() : _drift(0), _immediateDrift(0) {}
drift_t(int d, int expected) : _drift(d), _immediateDrift(expected) {}
drift_t(const drift_t& ro) : _drift(ro._drift), _immediateDrift(ro._immediateDrift) {}
drift_t& operator = (const drift_t& ro) { this->_drift = ro._drift; this->_immediateDrift = ro._immediateDrift; return *this; }
} ;//*/
int main() {
/*class drift_t{ //It doesn't works
public:
int _drift;
int _immediateDrift;
drift_t() : _drift(0), _immediateDrift(0) {}
drift_t(int d, int expected) : _drift(d), _immediateDrift(expected) {}
drift_t(const drift_t& ro) : _drift(ro._drift), _immediateDrift(ro._immediateDrift) {}
drift_t& operator = (const drift_t& ro) { this->_drift = ro._drift; this->_immediateDrift = ro._immediateDrift; return *this; }
} ;//*/
std::deque<drift_t> drift; drift.push_back(drift_t(0,0));drift.push_back(drift_t(-50,-50));
return 0;
}

Isn't the error the one that the compiler says it is? You can't use the local class for that template initialization.
Try compiling with -std=c++11 as I believe it relaxes on that.

Related

I'm getting a error when I declare a class as a member of other class. error : a class-key must be used when declaring a friend

I am a C++ rookie and I was experimenting with boost serialization and I wanted to see if it works when a class is declared as a member of another class. But when I compile my code I get loads of errors. I tried declaring baseds as a struct but no change in errors. My code :
#include <iostream>
#include <fstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
class baseds{};
class superior{};
class baseds {
private:
friend class boost::serialization::access;
public:
int a;
int b;
int c;
baseds(){}
~baseds(){}
template <class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & a;
ar & b;
ar & c;
}
};
class superior {
private:
friend class boost::serialization::access;
public:
int x;
int y;
baseds lag;
superior(){}
~superior(){}
template <class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & x;
ar & y;
ar & lag;
}
};
int main() {
superior myData,myData2;
myData.x=10;
myData.y=20;
myData.lag.a=1;
myData.lag.b=2;
myData.lag.c=3;
ofstream ofs("steps.txt");
{
boost::serialization::archive one(ofs);
one << myData;
}
ifstream ifs("steps.txt");
{
boost::serialization::archive two(ifs);
two >> myData2;
}
std::cout<<"\n"<<myData2.x;
std::cout<<"\n"<<myData2.y;
std::cout<<"\n"<<myData2.lag.a;
std::cout<<"\n"<<myData2.lag.b;
std::cout<<"\n"<<myData2.lag.c;
return 0;
}
errors:
tier2.cpp:10: error: a class-key must be used when declaring a friend
tier2.cpp:29: error: a class-key must be used when declaring a friend
tier2.cpp:32: error: expected `;' before "int"
tier2.cpp: In member function `void superior::serialize(Archive&, unsigned int)':
tier2.cpp:38: error: `x' undeclared (first use this function)
tier2.cpp:38: error: (Each undeclared identifier is reported only once for each function it appears in.)
tier2.cpp:39: error: `y' undeclared (first use this function)
tier2.cpp:40: error: `lag' undeclared (first use this function)
tier2.cpp: In function `int main()':
tier2.cpp:47: error: 'class superior' has no member named 'x'
tier2.cpp:48: error: 'class superior' has no member named 'y'
tier2.cpp:49: error: 'class superior' has no member named 'lag'
tier2.cpp:50: error: 'class superior' has no member named 'lag'
tier2.cpp:51: error: 'class superior' has no member named 'lag'
tier2.cpp:53: error: `ofstream' undeclared (first use this function)
tier2.cpp:53: error: expected `;' before "ofs"
tier2.cpp:55: error: `archive' is not a member of `boost::serialization'
tier2.cpp:55: error: expected `;' before "one"
tier2.cpp:56: error: `one' undeclared (first use this function)
tier2.cpp:57: error: expected `;' before '}' token
tier2.cpp:59: error: `ifstream' undeclared (first use this function)
tier2.cpp:59: error: expected `;' before "ifs"
tier2.cpp:61: error: `archive' is not a member of `boost::serialization'
tier2.cpp:61: error: expected `;' before "ones"
tier2.cpp:62: error: `ones' undeclared (first use this function)
tier2.cpp:63: error: expected `;' before '}' token
tier2.cpp:64: error: 'class superior' has no member named 'x'
tier2.cpp:65: error: 'class superior' has no member named 'y'
tier2.cpp:66: error: 'class superior' has no member named 'lag'
tier2.cpp:67: error: 'class superior' has no member named 'lag'
tier2.cpp:68: error: 'class superior' has no member named 'lag'
tier2.cpp:71:2: warning: no newline at end of file
You are re-defining both baseds and superior. You should get an error similar to
class baseds{}; // definition
class superior{}; // definition
// second definition
class baseds {
private:
....
error: redefinition of 'class baseds'
Remove the first pair of definitions.
You are defining baseds and superior twice.
On gcc you would get the proper error message:
main.cpp:9:7: error: redefinition of 'baseds'
class baseds {
^
main.cpp:6:7: note: previous definition is here
class baseds{};
^
main.cpp:27:7: error: redefinition of 'superior'
class superior {
^
main.cpp:7:7: note: previous definition is here
class superior{};
Seemingly your compiler does not recognize the redefinition and gets lost, producing the poor error message.
If you meant to provide a forward declaration of both classes, you need to lose the braces:
class baseds;
class superior;
class baseds {
/* ... */
};
But sice you don't use superior for the definition of baseds at all, you can leave out the forward declarations completely - for the definition of superior you need the definition of baseds, since you have a member of that type and therefore a forward declaration is not sufficient.
Sorry fellow stackoverflow citizens, this was a stupid question, figured out most of the errors after a good sleep
The correct code is as below:
#include <iostream>
#include <fstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
class baseds;
class superior;
class baseds {
private:
friend class boost::serialization::access;
public:
int a;
int b;
int c;
baseds(){}
~baseds(){}
template <class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & a;
ar & b;
ar & c;
}
};
class superior {
private:
friend class boost::serialization::access;
friend class baseds;
public:
int x;
int y;
baseds lag;
superior(){}
~superior(){}
template <class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & x;
ar & y;
ar & lag;
}
};
int main() {
superior myData,myData2;
myData.x=10;
myData.y=20;
myData.lag.a=1;
myData.lag.b=2;
myData.lag.c=3;
std::ofstream ofs("steps.txt");
{
boost::archive::text_oarchive one(ofs);
one << myData;
}
std::ifstream ifs("steps.txt");
{
boost::archive::text_iarchive two(ifs);
two >> myData2;
}
std::cout<<"\n"<<myData2.x;
std::cout<<"\n"<<myData2.y;
std::cout<<"\n"<<myData2.lag.a;
std::cout<<"\n"<<myData2.lag.b;
std::cout<<"\n"<<myData2.lag.c;
return 0;
}

I'm getting a error when I declare a class as a member of other class. error : a class-key must be used when declaring a friend [duplicate]

I am a C++ rookie and I was experimenting with boost serialization and I wanted to see if it works when a class is declared as a member of another class. But when I compile my code I get loads of errors. I tried declaring baseds as a struct but no change in errors. My code :
#include <iostream>
#include <fstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
class baseds{};
class superior{};
class baseds {
private:
friend class boost::serialization::access;
public:
int a;
int b;
int c;
baseds(){}
~baseds(){}
template <class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & a;
ar & b;
ar & c;
}
};
class superior {
private:
friend class boost::serialization::access;
public:
int x;
int y;
baseds lag;
superior(){}
~superior(){}
template <class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & x;
ar & y;
ar & lag;
}
};
int main() {
superior myData,myData2;
myData.x=10;
myData.y=20;
myData.lag.a=1;
myData.lag.b=2;
myData.lag.c=3;
ofstream ofs("steps.txt");
{
boost::serialization::archive one(ofs);
one << myData;
}
ifstream ifs("steps.txt");
{
boost::serialization::archive two(ifs);
two >> myData2;
}
std::cout<<"\n"<<myData2.x;
std::cout<<"\n"<<myData2.y;
std::cout<<"\n"<<myData2.lag.a;
std::cout<<"\n"<<myData2.lag.b;
std::cout<<"\n"<<myData2.lag.c;
return 0;
}
errors:
tier2.cpp:10: error: a class-key must be used when declaring a friend
tier2.cpp:29: error: a class-key must be used when declaring a friend
tier2.cpp:32: error: expected `;' before "int"
tier2.cpp: In member function `void superior::serialize(Archive&, unsigned int)':
tier2.cpp:38: error: `x' undeclared (first use this function)
tier2.cpp:38: error: (Each undeclared identifier is reported only once for each function it appears in.)
tier2.cpp:39: error: `y' undeclared (first use this function)
tier2.cpp:40: error: `lag' undeclared (first use this function)
tier2.cpp: In function `int main()':
tier2.cpp:47: error: 'class superior' has no member named 'x'
tier2.cpp:48: error: 'class superior' has no member named 'y'
tier2.cpp:49: error: 'class superior' has no member named 'lag'
tier2.cpp:50: error: 'class superior' has no member named 'lag'
tier2.cpp:51: error: 'class superior' has no member named 'lag'
tier2.cpp:53: error: `ofstream' undeclared (first use this function)
tier2.cpp:53: error: expected `;' before "ofs"
tier2.cpp:55: error: `archive' is not a member of `boost::serialization'
tier2.cpp:55: error: expected `;' before "one"
tier2.cpp:56: error: `one' undeclared (first use this function)
tier2.cpp:57: error: expected `;' before '}' token
tier2.cpp:59: error: `ifstream' undeclared (first use this function)
tier2.cpp:59: error: expected `;' before "ifs"
tier2.cpp:61: error: `archive' is not a member of `boost::serialization'
tier2.cpp:61: error: expected `;' before "ones"
tier2.cpp:62: error: `ones' undeclared (first use this function)
tier2.cpp:63: error: expected `;' before '}' token
tier2.cpp:64: error: 'class superior' has no member named 'x'
tier2.cpp:65: error: 'class superior' has no member named 'y'
tier2.cpp:66: error: 'class superior' has no member named 'lag'
tier2.cpp:67: error: 'class superior' has no member named 'lag'
tier2.cpp:68: error: 'class superior' has no member named 'lag'
tier2.cpp:71:2: warning: no newline at end of file
You are re-defining both baseds and superior. You should get an error similar to
class baseds{}; // definition
class superior{}; // definition
// second definition
class baseds {
private:
....
error: redefinition of 'class baseds'
Remove the first pair of definitions.
You are defining baseds and superior twice.
On gcc you would get the proper error message:
main.cpp:9:7: error: redefinition of 'baseds'
class baseds {
^
main.cpp:6:7: note: previous definition is here
class baseds{};
^
main.cpp:27:7: error: redefinition of 'superior'
class superior {
^
main.cpp:7:7: note: previous definition is here
class superior{};
Seemingly your compiler does not recognize the redefinition and gets lost, producing the poor error message.
If you meant to provide a forward declaration of both classes, you need to lose the braces:
class baseds;
class superior;
class baseds {
/* ... */
};
But sice you don't use superior for the definition of baseds at all, you can leave out the forward declarations completely - for the definition of superior you need the definition of baseds, since you have a member of that type and therefore a forward declaration is not sufficient.
Sorry fellow stackoverflow citizens, this was a stupid question, figured out most of the errors after a good sleep
The correct code is as below:
#include <iostream>
#include <fstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
class baseds;
class superior;
class baseds {
private:
friend class boost::serialization::access;
public:
int a;
int b;
int c;
baseds(){}
~baseds(){}
template <class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & a;
ar & b;
ar & c;
}
};
class superior {
private:
friend class boost::serialization::access;
friend class baseds;
public:
int x;
int y;
baseds lag;
superior(){}
~superior(){}
template <class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & x;
ar & y;
ar & lag;
}
};
int main() {
superior myData,myData2;
myData.x=10;
myData.y=20;
myData.lag.a=1;
myData.lag.b=2;
myData.lag.c=3;
std::ofstream ofs("steps.txt");
{
boost::archive::text_oarchive one(ofs);
one << myData;
}
std::ifstream ifs("steps.txt");
{
boost::archive::text_iarchive two(ifs);
two >> myData2;
}
std::cout<<"\n"<<myData2.x;
std::cout<<"\n"<<myData2.y;
std::cout<<"\n"<<myData2.lag.a;
std::cout<<"\n"<<myData2.lag.b;
std::cout<<"\n"<<myData2.lag.c;
return 0;
}

How to properly use a header file to be a complete class?

(Beginner programmer..) I'm following the style of a header file that worked fine, but I'm trying to figure out how I keep getting all of these errors when I compile. I am compiling with g++ in Cygwin.
Ingredient.h:8:13: error: expected unqualified-id before ‘)’ token
Ingredient.h:9:25: error: expected ‘)’ before ‘n’
Ingredient.h:19:15: error: declaration of ‘std::string <anonymous class>::name’
Ingredient.h:12:14: error: conflicts with previous declaration ‘std::string<anonymous class>::name()’
Ingredient.h:20:7: error: declaration of ‘int <anonymous class>::quantity’
Ingredient.h:13:6: error: conflicts with previous declaration ‘int<anonymous class>::quantity()’
Ingredient.h: In member function ‘std::string<anonymous class>::name()’:
Ingredient.h:12:30: error: conversion from ‘<unresolved overloaded function type>’ to non-scalar type ‘std::string’ requested
Ingredient.h: In member function ‘int<anonymous class>::quantity()’:
Ingredient.h:13:25: error: argument of type ‘int (<anonymous class>::)()’ does not match ‘int’
Ingredient.h: At global scope:
Ingredient.h:4:18: error: an anonymous struct cannot have function members
Ingredient.h:21:2: error: abstract declarator ‘<anonymous class>’ used as declaration
And here is my class header file...
#ifndef Ingredient
#define Ingredient
class Ingredient {
public:
// constructor
Ingredient() : name(""), quantity(0) {}
Ingredient(std::string n, int q) : name(n), quantity(q) {}
// accessors
std::string name() { return name; }
int quantity() {return quantity; }
// modifier
private:
// representation
std::string name;
int quantity;
};
#endif
I am confused by these errors and don't really know what I am doing wrong concerning the implementation of the class..
That's a funny one. You are essentially killing your class name by #define Ingredient - all occurrences of Ingredient will be erased. This is why include guards generally take the form of #define INGREDIENT_H.
You are also using name both for the member and the getter function (probably an attempt to translate C#?). This is not allowed in C++.
How about look on errors? variables and functions can't have same names. And include guard should never names such as class.
#ifndef INGREDIENT_H
#define INGREDIENT_H
class Ingredient {
public:
// constructor
Ingredient() : name(""), quantity(0) {}
Ingredient(std::string n, int q) : name(n), quantity(q) {}
// accessors
std::string get_name() const { return name; }
int get_quantity() const {return quantity; }
// modifier
private:
// representation
std::string name;
int quantity;
};
#endif

object as function argument

I have written a simple program.
I am getting this error:
time.cpp: In function ‘int main()’:
time.cpp:22:9: error: expected ‘;’ before ‘a’
time.cpp:23:4: error: ‘a’ was not declared in this scope
time.cpp:24:4: error: ‘b’ was not declared in this scope
time.cpp:25:4: error: ‘c’ was not declared in this scope
This is my code:
#include<iostream>
using namespace std;
class time
{
int hour;
int min;
public:
void gettime(int h,int m)
{
hour=h;
min=m;
}
void puttime()
{
cout<<hour<<endl<<min;
}
void sum(time x,time y)
{
min=x.min+y.min;
hour=min/60;
min=min%60;
hour=hour+x.hour+y.hour;
}
};
int main()
{
time a,b,c;
a.gettime(2,45);
b.gettime(3,35);
c.sum(a,b);
a.puttime();
b.putime();
c.puttime();
return 0;
}
Remember that there is a standard function named time.
This is the one main reason you should refrain from using namespace std;.
b.putime() must be b.puttime() here. Otherwise this code compiled

Complex number printing program malfunctioning

I have started working on C++ language.I am very new to it.The program takes a complex number from the user and prints it out.But its giving me many errors like,
prog.cpp: In function ‘int main()’:
prog.cpp:26: error: ‘GetReal’ was not declared in this scope
prog.cpp:26: error: ‘SetReal’ was not declared in this scope
prog.cpp:27: error: ‘GetImag’ was not declared in this scope
prog.cpp:27: error: ‘SetImag’ was not declared in this scope
prog.cpp:28: error: ‘print’ was not declared in this scope
prog.cpp: At global scope:
prog.cpp:34: error: expected unqualified-id before ‘)’ token
prog.cpp:40: error: expected unqualified-id before ‘float’
prog.cpp:40: error: expected `)' before ‘float’
prog.cpp: In function ‘void SetImag(float)’:
prog.cpp:64: error: ‘real’ was not declared in this scope
prog.cpp: In function ‘void SetReal(float)’:
prog.cpp:68: error: ‘imag’ was not declared in this scope
prog.cpp: In function ‘void print()’:
prog.cpp:73: error: ‘Cout’ was not declared in this scope
prog.cpp:73: error: ‘real’ was not declared in this scope
prog.cpp:73: error: ‘imag’ was not declared in this scope
Here's the code:
/*
Date=13 January 2011
Program: To take a complex number from the user and print it on the screen */
/*Defining a class*/
#include <iostream>
using namespace std;
class complex
{
float real;
float imag;
public:
complex();
complex(float a,float b);
float GetReal();
float GetImag();
void SetReal();
void SetImag();
void print();
};
int main()
{
complex comp;
SetReal(GetReal());
SetImag(GetImag());
print();
}
complex()
{
real=0;
imag=0;
}
complex(float a,float b)
{
real=a;
imag=b;
}
float GetReal()
{
float realdata;
cout<<"Enter Real part:"<<endl;
cin>>realdata;
return realdata;
}
float GetImag()
{
float imagdata;
cout<<"Enter Imaginary part"<<endl;
cin>>imagdata;
return imagdata;
}
void SetImag(float a)
{
real=a;
}
void SetReal(float b)
{
imag=b;
}
void print()
{
printf("The Complex number is %f+%fi",real,imag);
}
Since GetReal() et al are declared as part of the complex class, you should call them on the object you created:
complex comp;
comp.SetReal(comp.GetReal());
comp.SetImag(comp.GetImag());
comp.print();
Similarly, you need to scope the implementation of the complex constructor:
complex::complex()
{
real=0;
imag=0;
}
The same applies to the other member functions not shown in your post.
In your main function you need to call GetReal and SetReal on an instance of the class:
e.g.
Complex comp;
comp.SetReal();
...
Also, your method bodies aren't bound to the class, they're floating in the global namespace. You need to define them:
void Complex::SetReal() {} //etc
Hope this helps