C++ typedef and struct question - c++

typedef struct
{
int y;
int weight;
struct edgenode * next;
}edgenode;
This code is giving error : 'edgenode' : redefinition; different basic types
It works fine in C code.
Why?

Because your struct doesn't have a name! The question suggests a C heritage - the code is written the way I'd write it.
The pure C++ solution is:
struct edgenode
{
int y;
int weight;
edgenode *next;
};
This will not work in C. In C, and consistent with the question, you would write:
typedef struct edgenode
{
int y;
int weight;
struct edgenode * next;
} edgenode;
Now your struct has a name - struct edgenode. There is also a typedef for it, of course - edgenode, but the compiler doesn't know about that name until it reaches the final semi-colon (approximately). You could also write:
typedef struct edgenode edgenode;
struct edgenode
{
int y;
int weight;
edgenode *next;
};

try:
struct edgenode
{
int y;
int weight;
edgenode* next;
};
In C++ it is no longer required to use the typedef on struct nodes.
Also the way you were using it (for C) was wrong. if you typedef it then there is no need to use struct anymore.
In C you had todo:
// In C:
struct X {};
struct X a;
// C with typedef (Notice here that the struct is anonymous)
// Thus it is only accessible via the typedef (but you could give it a name)
typedef struct {} X;
X a;
// In C++ the use of struct is no longer required when declaring the variable.
struct Y {};
Y a;

No name specified for your struct before you typedef
typedef struct edgenode
{
int y;
int weight;
edgenode* next;
}en;

The difference between C and C++ is, that they treat struct-names and typedef names differently. In C you can not refer to a struct without using the "struct" keyword unless you create typedef name which resolves to the struct name. Therefore this is valid in C, but not in C++:
struct A {};
typedef int A;
int main()
{
A a;
struct A a;
}
structs and typedefs live in a different namespace if you want to. However in C++, both struct and typedef names go into the same namespace. There can be only one A and therefore this example does not compile. So how does this apply to your example? Let's read it the C way:
typedef struct // Here's an unnamed struct
{
int y;
int weight;
struct edgenode * next; // Oh, yes points to some struct called "edgenode" that we don't know of
}edgenode; // and we want to refer to this structs as "edgenode"
This declaration actually created two things called edgenode: A typedef (for the unnamed struct) and an incomplete type "struct edgenode" that is not defined anywhere. You will notice that edgenode x; x.next->y will not compile.
Here's how C++ reads it:
typedef struct // Here's an unnamed struct
{
int y;
int weight;
struct edgenode * next; // Oh, yes points to some struct called "edgenode" that we don't know of
}edgenode; // and we want to refer to this as "edgenode"..HEY WAITASECOND! There's already SOME OTHER THING named edgenode. We know this, because "next" mentioned it!!

Related

Can a structure with union members be qualified as POD?

Can this structure MyWrapStruct:
struct MyWrapStruct
{
bool myBool;
union
{
struct
{
void* myPtr;
int myInt;
};
Struct1 myStruct1;
Struct2 myStruct2;
} myStructs;
};
With "sub-structures" :
struct Struct1
{
void* myPtr;
int myInt;
float mySpecialFloat;
};
struct Struct2
{
void* myPtr;
int myInt;
int mySpecialInt;
};
Be considered a POD structure?
Yes - even union types merely contains data, and no methods, constructors, etc.
See:
What are POD types in C++?
Update
Provided, of course, the union only contains POD types.
See:
Questions regarding C++ non-POD unions

typedef usage in struct definition

I have problem with this code,this is a header file(stack.h) from a maze program. i was studying Stack structure, and in my documents, i couldn't understand these type of structures, can anyone explain to me why we are using typedef and how the 12th and 21st line works??
#ifndef STACK_H
#define STACK_H
#define STACKSIZE 50
typedef struct d {
int x;
int y;
int right; int left;
int down;
int up;
int camefrom;
} StackDataType, position; /// LINE 12
struct STACK{
StackDataType element[STACKSIZE]; int top;
void create();
void close();
bool push(StackDataType); StackDataType pop();
bool isempty();
};
typedef struct STACK Stack; /// LINE 21
#endif
I think you do not need to typedef a struct again in C++, it again defines a struct, which is unnecessary. You can just define:
struct d{
};
In my (considerable) experience, this almost always denotes a C programmer who has fumbled their way into C++. If these are notes from your classes, it doesn't bode well.
In the earliest "C", if you declared a struct
struct StructName {
int a;
int b;
};
This didn't declare a type name, it only declared a struct name, so to make an instance of StructName you would have to write:
struct StructName myStruct;
If you wanted to be able to omit the "StructName" part you would need to use a typedef:
struct StructName { int a, b; };
typedef struct StructName StructName;
Or you could combine these into one, somewhat confusing, statement:
typedef struct StructName { int a, b; } StructName;
I say confusing because if the struct definition is many lines long, it could be confused for a second C syntax which lets you declare an instance of a Struct after defining the type:
struct StructName { int a, b; } StructName;
// aka
struct StructName { int a, b; };
struct StructName StructName; // local variable, StructName of type struct StructName
// declare a VARIABLE called StructName which is of type anonymous-struct.
struct { int a, b; } StructName;
One problem with this is that you can't use the typedef'd name in the structure declaration:
// Won't compile because 'List' isn't declared until the end.
typedef struct list_structure { List* next; int a; } List;
// Won't compile because you have to remember to say 'struct List'
typedef struct List { List* next; int a; } List;
// Compiles
typedef struct list_structure { struct list_structure* next; int a; } List;
This confused a lot of C programmers. Enough so that many C programmers will tell you that the definition of a struct is
typedef struct tag_name { /* struct details */ } structname;
//e.g.
typedef struct tagStructName { int a, b; } StructName;
C++ inherited all of this, but also went ahead and made the typedef implied for you:
// doesn't compile as C, will compile as C++
struct List {
List* next;
int a;
};
To see it not compiling as C: http://ideone.com/3r9TRy
In C++, declaring something as a class is exactly the same as declaring it a struct, with one change:
class List {
List* next;
public:
int a;
};
Is EXACTLY as though you had written:
struct List {
private:
List* next;
public:
int a;
};
There's no other difference between a struct and a class in C++.
I can see two problems: The first is the mysterious symbol  in the definition of the d structure. The second is that you use typedef for that structure too, but have something after the typename StackDataType. The second error you get is probably just because of the first one, it's very common in C and C++ to get errors in unrelated lines because of previous errors.
Besides, in C++ you don't really need typedef for structures, as they are the same as classes so doing e.g. struct StackDataType {...}; will allow you to use StackDataType as a type.
What's going on is that essentially the typedef is being used to create a shorthand way to refer to the given structure.
So in this example, both StackDataType and position are shorthand references to what is formally declared as struct d, and Stack is a shorthand reference to what is formally declared as struct STACK.
Generally speaking, this allows for cleaner code referencing these structures. E.g., instead of having to write:
struct STACK var;
to declare an instance of this structure, you can just use:
Stack var;
You can declare a typedef either at the same point at which you declare the type (as in the first example), or you can declare it later (as in the second).

How to simplify structs using a template?

I have a piece of code, copied below, with really similar structs in which just one member changes type. I am looking to simplify it. I was considering using a template, but I am not too sure how would it be the syntax between a struct and a template. Any pointer would be greatly appreciated.
typedef struct pos_parameter{
float magnitud;
bool new_value;
} pos_parameter;
typedef struct feed_parameter{
double magnitud;
bool new_value;
} feed_parameter;
typedef struct speed_parameter{
long magnitud;
bool new_value;
} speed_parameter;
typedef struct g_code_parameter{
int magnitud;
bool new_value;
} g_code_parameter;
typedef struct position{
pos_parameter X;
pos_parameter Y;
pos_parameter Z;
pos_parameter A;
} position;
typedef struct move{
position pos;
feed_parameter feedrate;
speed_parameter speed;
g_code_parameter g_code;
} move;
template <typename T>
struct parameter{
T magnitud;
bool new_value;
};
Example use:
parameter<float> pos_parameter;
parameter<double> feed_parameter;
parameter<long> speed_parameter;
parameter<int> code_parameter;
Hope that helps.
One quick observation before we get in to genericizing the magnitud member variable. Your use of the typedef struct {/*...*/} name; syntax is not needed, and very non-idiomatic in C++. In C this may be needed, but C++ is not C. In C++, you can simply:
struct Gizmo
{
/* ... */
};
Now, in order to genericize the type of the magnitud member variable, you can create a class template like this:
template<class MAG> struct basic_parameter
{
MAG magnitud;
bool new_value;
};
You would declare an instance of such a thing like this:
basic_parameter<int> myparam;
You can also use a typedef to create a kind of "alias" for certian specializations of basic_parameter, like this:
typedef basic_param<int> int_param; // Now int_param is shorthand for basic_param<int>
/* ... */
int_param myparam; // myparam is of type basic_param<int>
You can use this technique to create typedefs for all the different kinds of parameters you were using in the position and move structures, and make it so that you don't have to change the code for those types.
Here is a complete solution:
template<class MAG> struct basic_parameter
{
MAG magnitud;
bool new_value;
};
typedef basic_parameter<float> pos_parameter;
typedef basic_parameter<double> feed_parameter;
typedef basic_parameter<long> speed_parameter;
typedef basic_parameter<int> g_code_parameter;
struct position {
pos_parameter X;
pos_parameter Y;
pos_parameter Z;
pos_parameter A;
};
struct move
{
position pos;
feed_parameter feedrate;
speed_parameter speed;
g_code_parameter g_code;
};
int main()
{
}
I guess the first four could be :
template<typename T>
struct pos_parameter{
T magnitud;
bool new_value;
};
template<typename T>
struct generic_parameter
{
T magnitud;
bool new_value;
};
There you go

How to use a struct inside another struct?

I want to use a nested structure, but I don't know how to enter data in it. For example:
struct A {
int data;
struct B;
};
struct B {
int number;
};
So in main() when I come to use it:
int main() {
A stage;
stage.B.number;
}
Is that right? If not how do I use it?
Each member variable of a struct generally has a name and a type. In your code, the first member of A has type int and name data. The second member only has a type. You need to give it a name. Let's say b:
struct A {
int data;
B b;
};
To do that, the compiler needs to already know what B is, so declare that struct before you declare A.
To access a nested member, refer to each member along the path by name, separated by .:
A stage;
stage.b.number = 5;
struct A {
struct B {
int number;
};
B b;
int data;
};
int main() {
A a;
a.b.number;
a.data;
}
struct B { // <-- declare before
int number;
};
struct A {
int data;
B b; // <--- declare data member of `B`
};
Now you can use it as,
stage.b.number;
The struct B within A must have a name of some sort so you can reference it:
struct B {
int number;
};
struct A {
int data;
struct B myB;
};
:
struct A myA;
myA.myB.number = 42;
struct A
{
int data;
struct B
{
int number;
}b;
};
int main()
{
A stage = { 42, {100} };
assert(stage.data == 42);
assert(stage.b.number == 100);
}
struct TestStruct {
short Var1;
float Var2;
char Var3;
struct TestStruct2 {
char myType;
CString myTitle;
TestStruct2(char b1,CString b2):myType(b1), myTitle(b2){}
};
std::vector<TestStruct2> testStruct2;
TestStruct(short a1,float a2,char a3): Var1(a1), Var2(a2), Var3(a3) {
testStruct2.push_back(TestStruct2(0,"Test Title"));
testStruct2.push_back(TestStruct2(4,"Test2 Title"));
}
};
std::vector<TestStruct> testStruct;
//push smthng to vec later and call
testStruct.push_back(TestStruct(10,55.5,100));
TRACE("myTest:%s\n",testStruct[0].testStruct2[1].myTitle);
I have somewhat like the following code running for a while live now and it works.
// define a timer
struct lightTimer {
unsigned long time; // time in seconds since midnight so range is 0-86400
byte percentage; // in percentage so range is 0-100
};
// define a list of timers
struct lightTable {
lightTimer timer[50];
int otherVar;
};
// and make 5 instances
struct lightTable channel[5]; //all channels are now memory allocated
#zx485: EDIT: Edited/cleaned the code. Excuse for the raw dump.
Explanation:
Define a lightTimer. Basically a struct that contains 2 vars.
struct lightTimer {
Define a lightTable. First element is a lightTimer.
struct lightTable {
Make an actual (named) instance:
struct lightTable channel[5];
We now have 5 channels with 50 timers.
Access like:
channel[5].timer[10].time = 86400;
channel[5].timer[10].percentage = 50;
channel[2].otherVar = 50000;

Is there anyway to create a non-type template parameter for a class but not declare using <>?

My original code looks like this:
class a{
...
char buff[10];
}
and im attempting to make this change to the code:
template <int N = 10>
class a{
...
char buff[N];
}
Is there any thing I can do to keep my existing code creating instances of class a like this:
a test;
instead of making the change to:
a<> test;
to get the default parameter?
You can't instantiate a template without angle-brackets, and you can't give a type the same name as a template, so you can't do exactly what you want.
You could give the template a different name, and typedef a to the default-sized one.
Well, don't make the class a template is the obvious answer - use something like:
class a {
public:
a( int n = 10 ) : buff(n) {}
private:
std::vector <char> buff;
};
Not in really good ways. You can typedef X to be X<> in a different namespace:
namespace lib {
template<int N=10>
struct X
{
int t[N];
};
}
typedef lib::X<> X;
int main()
{
X a;
lib::X<20> b;
}
-- or --
template<int N=10>
struct X
{
int t[N];
};
int main()
{
typedef X<> X; // functions have their own namespace!
X a;
::X<20> b;
}
Nope. The empty angle brackets are required.