Re: declare a struct with c++ vectors in a header file...
On Jun 17, 1:17 pm, "Alf P. Steinbach" <al...@start.no> wrote:
* beet:
On Jun 16, 11:28 pm, "Alf P. Steinbach" <al...@start.no> wrote:
* Eric Pruneau:
* "beet" <whh...@gmail.com>:
I tried to declare a c++ struct like following in a header file:
------
1 #ifndef _SEARCHDATA_H_
2 #define _SEARCHDATA_H_
Never define names starting with underscore followed by uppercase lette=
r.
Those are reserved for the C++ implementation.
That also goes for use of double underscore.
3
4 #include <vector>
5 #include <list>
6
add :
using namespace std;
or you gonna have to be type 'std::vector' instead of just 'vector'.
vector (list too) is a class inside the namespace std.
I'm sorry, but that is extremely bad advice.
Never add "using namespace std;" in a header file. It will force unqual=
ified
names from the standard library, on all code that uses the header file.=
And in
particular, "string" and "vector" are commonly used names for other thi=
ngs than
the standard library classes, and you really don't want to screw up thi=
ngs for
code that uses those names -- that's why the standard library use=
s "std::".
Conversely, when you see "using namespace std;" in a header file then y=
ou know
that the author is incompetent or an utter novice.
Cheers, & hth.,
- Alf
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Please don't quote signatures.
Thanks for your replies...
I modified a bit my code according to your comments, but it seems
problems with declaration of functions:
g++ -Wall -g -c searchData.cpp
searchData.cpp: In function `int searchPt(std::vector<int,
std::allocator<int> >&, searchIter&, double&, double&)':
searchData.cpp:46: warning: comparison between signed and unsigned
integer expressions
This is from code you haven't shown. It's just a warning but you should fi=
x it.
Typical fix to is use 'size_t' for a loop variable.
g++ -Wall -g -o runinv functionfile.o retroSearch.o searchData.o
simlib.o myinv.o mxCalc.o optSolver.o
optSolver.o(.text+0x1d27): In function `egSearch(std::vector<double,
std::allocator<double> >&, double, float&, double&, searchIterInfo&,
float)':
/home/wang75/myResearch/generic/simContSearch/optSolver.cpp:351:
undefined reference to `getInitStep(std::vector<double,
std::allocator<double> > const&, std::vector<double,
std::allocator<double> >&, int, float, int)'
This an undefined reference because the message says "undefined reference"=
..
That means the object files you're linking don't have an implementation of=
that
function.
Probably it's due to a signature mismatch for something you think is an
implementation.
optSolver.o(.text+0x1ffb):/home/wang75/myResearch/generic/
simContSearch/optSolver.cpp:382: undefined reference to
`getInitStep(std::vector<double, std::allocator<double> > const&,
std::vector<double, std::allocator<double> >&, int, float, int)'
optSolver.o(.text+0x4039): In function `fcn(std::vector<double,
std::allocator<double> > const&, std::vector<double,
std::allocator<double> >&, double, searchIterInfo&, int, int, float)':
/home/wang75/myResearch/generic/simContSearch/optSolver.cpp:711:
undefined reference to `simplexInterp(std::vector<double,
"undefined reference"
std::allocator<double> > const&, std::vector<std::vector<int,
std::allocator<int> >, std::allocator<std::vector<int,
std::allocator<int> > > >&, std::vector<double, std::allocator<double>
&, std::vector<int, std::allocator<int> >&, int, float, int)'
optSolver.o(.text+0x465c): In function `fcnPart(std::vector<double,
std::allocator<double> > const&, std::vector<double,
std::allocator<double> >&, double, int, searchIterInfo&, int, int,
float)':
/home/wang75/myResearch/generic/simContSearch/optSolver.cpp:768:
undefined reference to `simplexInterp(std::vector<double,
"undefined reference"
std::allocator<double> > const&, std::vector<std::vector<int,
std::allocator<int> >, std::allocator<std::vector<int,
std::allocator<int> > > >&, std::vector<double, std::allocator<double>
&, std::vector<int, std::allocator<int> >&, int, float, int)'
collect2: ld returned 1 exit status
make: *** [runinv] Error 1
shell returned 2
----my code ---
1 #ifndef _searchData_
2 #define _searchData_
Generally only use ALL UPPERCASE for macro names, and never use that conve=
ntion
for other names, so as to avoid possible name collisions (macros don't res=
pect
scopes) -- this is a FAQ.
I should have been less specific about underscore advice.
As a rule, never use any leading underscore whatsoever, because in the glo=
bal
namespace those names are reserved for the implementation, and it's easies=
t to
just never use them rather than remember where they're not reserved.
3 #include <vector>
4 #include <list>
5
6 typedef struct searchIterInfo {
This is a C-ism, not necessary in C++. The C construct
typedef struct { blah blah } SomeName;
is, in C++, better expressed as
struct SomeName { blah blah };
7 searchIterInfo ():
8 contPts(0), //continuous trial points
9 contFvs(0), //fv for cont points
10 contFerrors(0), //std errors for cont points
11 gradients(0), //list of gradients
12 intPts(0), //evaluated int points
13 intFvs(0), //function values for in=
t points
14 intFerrors(0), //errors for int points
15 intPtList(0), //the monotone list of point=
s
16 simList(0), //the simplex list
17 seedVals(0), //the seed values
18 hMtx(0) {}; //the estimated hesian mat=
rix
Extraneous semicolon after right brace.
Anyway you don't need to define the vector initializations because they're=
what
you get by default. :-)
What you do need to initialize is what you've forgotten to initialize, nam=
ely
the members of built-in type 'iterID' and 'sampleSize': since they're not =
of
class type they don't have automatic default initialization.
19
20 std::vector< std::vector<double> > contPts;
21 std::vector<double> contFvs;
22 std::vector<double> contFerror=
s;
23 std::vector< std::vector<double> > gradients;
24 std::vector< std::vector<int> > intPts;
25 std::vector<double> intFvs;
26 std::vector<double> intFerrors=
;
tList;
ist;
29 std::vector<int> seedVa=
ls;
30 std::vector< std::vector<double> > hMtx;
31 int iterID; //the sample path =
index
32 double sampleSize; //the sample size for th=
is sp
Since the above doesn't communicate any purpose to me, it probably will no=
t
communicate any purpose to you either when you have been away from the cod=
e for
some time. So better more self-describing names would probably be a good i=
dea.
It's also possible, but by no means sure, that you're doing an unnecessary=
inversion of data structure, using a struct of vectors when problem domain=
calls
for a vector of structs -- generally a struct of like vectors indicate tha=
t. :-)
33 } searchIter;
34
35 std::vector<int> getBestIntPt(searchIter &);
36 int searchPt(std::vector<int> &, searchIter &, double &,
double &);
37 void addPt(std::vector<int> &, searchIter &, double fv, do=
uble
fr);
38
39 #endif
Cheers, & hth.,
- Alf
- Show quoted text -
Thanks Alf,
the functions are declared and defined in simInterp.h and
simInterp.cpp respectively:
----code---
#ifndef __SIMINTERP_H__
#define __SIMINTERP_H__
void getBinary(int, vector<int> &, int);
int getDecimal(vector<int> &);
void simplexInterp(vector<double> const&, vector< vector<int> > &,
vector<double> &,
vector<int> &, int = 0, float = 1.0, int = 0);
double getInitStep(const vector<double>&, vector<double> &, int = 0,
float = 1.0, int = 0);
#endif
*****
#include "simInterp.h"
#include <vector>
#include <iostream>
#include <math.h>
void simplexInterp(vector<double> const& x, vector< vector<int> >
&simVerts, vector<double> &wts,
vector<int> &permu, int simCode, float csize, int patCode)
{
...
}
double getInitStep(const vector<double> &x, vector<double> &d, int
simCode, float csize, int bMax)
{
....
}
-----end of code---
I cannot find anything wrong here.
again, thank you very much for your kind help.
Beet