Type visibility

S

saneman

I have made two modules:

1) main.cpp
Contains a main function and struct P.
Includes head.h and std::vector

#include "head.h"
#include<vector>
#include<iostream>
struct P {
int x;
int y;
};

int main() {
typedef std::vector<P> container;
container v;
P p;
p.x = 22;
p.y = 33;
v.push_back(p);


A<container> a(v);
int res = a.getValue();
std::cout << res << std::endl;
return 0;
}




2) head.h
A header file that contains the class A.

template <typename T >
class A {
public:
T t;

A(T t_){
t = t_;
}
int getValue() {
int res = (*t.begin()).x;
return res;

}
};




In class A getValue() returns the x field of the struct defined in main.cpp.
But how does class A know about the type 'P' which is only created in main?
 
D

David Côme

I have made two modules:

1) main.cpp
Contains a main function and struct P.
Includes head.h and std::vector

#include "head.h"
#include<vector>
#include<iostream>
struct P {
int x;
int y;
};

int main() {
typedef std::vector<P> container;
container v;
P p;
p.x = 22;
p.y = 33;
v.push_back(p);


A<container> a(v);
int res = a.getValue();
std::cout << res << std::endl;
return 0;
}




2) head.h
A header file that contains the class A.

template <typename T >
class A {
public:
T t;

A(T t_){
t = t_;
}
int getValue() {
int res = (*t.begin()).x;
return res;

}
};




In class A getValue() returns the x field of the struct defined in
main.cpp.
But how does class A know about the type 'P' which is only created in
main?

A doesn't know P. He knows just T must have a public member named x.
Replace typedef std::vector<P> container; by
typedef std::list<Q> container; with struct Q {int x;} and it will works
fine.
 
P

Pascal J. Bourguignon

saneman said:
I have made two modules:
Good.


1) main.cpp
2) head.h

Wrong.


If you have two modules, you should have five files:

interface implementation
Module A: ModuleA.h ModuleA.cpp
Module B: ModuleB.h ModuleB.cpp
Main: main.cpp

Assuming ModuleB uses ModuleA, and main uses both modules, you will have:

------(ModuleA.h)-----------------------
#ifndef ModuleA_h
#define ModuleA_h

// public definitions of module A

#endif
----------------------------------------


------(ModuleA.cpp)---------------------
#include <ModuleA.h>

// implementation of module A

----------------------------------------



------(ModuleB.h)-----------------------
#ifndef ModuleB_h
#define ModuleB_h

#include <ModuleA.h>

// public definitions of module B

#endif
----------------------------------------


------(ModuleB.cpp)---------------------
#include <ModuleB.h>

// implementation of module B

----------------------------------------


------(main.cpp)------------------------
#include <ModuleA.h>
#include <ModuleB.h>

// implementation of main:
int main(int argc,char** argv,char** envv){
ModuleA::doSomething();
ModuleB::doSomething();
return(0);
}

----------------------------------------



Note that you cannot have cross dependencies between the interfaces of
the modules, but you may have cross dependencies between
implementations and interfaces:

ModuleC.cpp could include ModuleD.h
and ModuleD.cpp could include ModuleC.h

this would mean that both modules C and D are at the same layer.

Otherwise the dependencies between the modules correspond to the
layers structuring the software.
 
S

saneman

David Côme said:
A doesn't know P. He knows just T must have a public member named x.
Replace typedef std::vector<P> container; by
typedef std::list<Q> container; with struct Q {int x;} and it will works
fine.

But if the struct contains more fields the only way to make it work is using
templates right?
 
E

Erik Wikström

I have made two modules:

1) main.cpp
Contains a main function and struct P.
Includes head.h and std::vector

#include "head.h"
#include<vector>
#include<iostream>

I would include my own headers after the standard headers.
2) head.h
A header file that contains the class A.

template <typename T >
class A {
public:
T t;

A(T t_){
t = t_;
}
int getValue() {
int res = (*t.begin()).x;
return res;

}
};

In class A getValue() returns the x field of the struct defined in main.cpp.
But how does class A know about the type 'P' which is only created in main?

Because of how the preprocessor and #include works. When the pre-
processor sees the #include line it replaces that line with the contents
in the specified fields. This means that when the compiler gets main.cpp
it contains first the definition of A (followed by contents of vector
and iostream) and then P and finally main(). So when the compiler tries
to instantiate A it know everything about both A and P.
 
E

Erik Wikström

Wrong.


If you have two modules, you should have five files:

interface implementation
Module A: ModuleA.h ModuleA.cpp
Module B: ModuleB.h ModuleB.cpp
Main: main.cpp

Or, if you count main as a module you only need on header:

interface implementation
Module A: ModuleA.h ModuleA.cpp
Main: main.cpp
 
J

James Kanze

I have made two modules:
1) main.cpp
Contains a main function and struct P.
Includes head.h and std::vector
#include "head.h"
#include<vector>
#include<iostream>
struct P {
int x;
int y;
};
int main() {
typedef std::vector<P> container;
container v;
P p;
p.x = 22;
p.y = 33;
v.push_back(p);
A<container> a(v);
int res = a.getValue();
std::cout << res << std::endl;
return 0;
}
2) head.h
A header file that contains the class A.
template <typename T >
class A {
public:
T t;

A(T t_){
t = t_;
}
int getValue() {
int res = (*t.begin()).x;
return res;
}
};
In class A getValue() returns the x field of the struct
defined in main.cpp. But how does class A know about the type
'P' which is only created in main?

As Pete said, there is no class A, only a class template A (and
later, a class A<container>). When parsing a template
definition, the compiler divides all names and expressions into
dependent and non-dependent; anything which is dependent only
gets looked up when the template is instantiated. The rules as
to when something is dependent, and when it's not, are fairly
complicated, as are the rules concerning dependent name look-up.
I'd suggest you get a good book about templates, such as "C++
Templates: the Complete Guide" (by Vandevoorde and Josuttis),
and study it carefully.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top