std::deque< class > member variable within class - A little help please

D

Dan Trowbridge

He everyone,

I am just getting started with .NET and I am having a porting problem.
I get and error in code that lookssomething like this (really stripped down
but you get the idea)...

class dt
{
std::deque< class dt > dtdq;
};

That is a class that contains a deque of class objects of it's own type.

Code like this use to compile just fine under VC6.

Under VS.NET the compiler tells me that 'dt' is not defined when it trys to
compile this. I get the following...

c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\deque(59) :
error C2027: use of undefined type
'dt'c:\dan\cwork\transolv\transolvDoc.cpp(28) : see declaration of 'dt'
c:\dan\cwork\transolv\transolvDoc.cpp(29) : see reference to class template
instantiation 'std::deque<_Ty>' being compiled
with
[
_Ty=dt
]
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\deque(60) :
error C2027: use of undefined type 'dt'
c:\dan\cwork\transolv\transolvDoc.cpp(28) : see declaration of 'dt'
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\deque(61) :
error C2027: use of undefined type 'dt'
c:\dan\cwork\transolv\transolvDoc.cpp(28) : see declaration of 'dt'
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\deque(62) :
error C2027: use of undefined type 'dt'
c:\dan\cwork\transolv\transolvDoc.cpp(28) : see declaration of 'dt'


It looks like the "updated" STL needs to know the size of the 'dt' class
when it trys to compile the code but since it is inside the class it hasn't
figured it's size out yet.
It looks like it is also assigning the type 'dt' to a varaible inside the
deque template class.

Is there work-around someone knows about? I use this design feature in a
lot of code I developed in VC6 and it represents a major re-write if I can't
figure away around this.

Thanks in advance
Dan Trowbridge
 
C

Carl Daniel [VC++ MVP]

Dan said:
He everyone,

I am just getting started with .NET and I am having a porting problem.
I get and error in code that lookssomething like this (really
stripped down but you get the idea)...

class dt
{
std::deque< class dt > dtdq;
};

That is a class that contains a deque of class objects of it's own
type.

This is not legal C++ - it's illegal to instantiate any standard library
class on an incomplete type.
Is there work-around someone knows about? I use this design feature
in a lot of code I developed in VC6 and it represents a major
re-write if I can't figure away around this.

Better get busy re-writing.

-cd
 
D

Dan Trowbridge

Bummer - but thanks for the info.

Dan


Carl Daniel said:
This is not legal C++ - it's illegal to instantiate any standard library
class on an incomplete type.


Better get busy re-writing.

-cd
 
D

Dan Trowbridge

Carl,

Do you have a suggestion of a way to obtain the same functionallity this
construct affords me.

I use this many places in quite a few codes.

An example is a matrix class where the "current" or "this" matrix is the
matrix sum of all the matrices in the deque, each is in-turn the sum of all
the matrices in its deque and so on. If the deque is emplty then data
stored in the matrix class is used to define the "this" matrix. In the case
I am describing I am using the BOOST UBLAS library to actually store the
matrices and do the matrix multiplication.

Again, this is just one example. I do this type of things many places, eg.

-Storing temperature dependant material properties where the values at the
root class object contains values interpolated for a given temperature
between the appropriate material properties in listed in the deque for
specific termperatures.

-Parsing files where each "card" (I'm starting to show my age) class
contains a deque of other "cards" in the file based on keyword, subkeywords,
etc. Feed the head of the class "tree" the heiarchial keywords and it
parses and sorts an appropraitly formatted file.

You get the idea. All these and more have been working fine for years now.

Any design ideas would be appreciated. Right now my boss is not happy that
all the code I have written using this flawed design is now broken so I
would like to figure out a good fix fast.

Thanks for your response
Dan
 
C

Carl Daniel [VC++ MVP]

Dan -

Normally the approach would be to store pointers instead of class instances.
You might try replacing std::deque<Foo> with
std::deque<boost::shared_ptr<Foo> >. That way all of the memory management
will be taken care of for you (as it is with the non-portable solution
you're using now). The resulting code will likely be more efficient too,
since your Foo's won't have to be copied when the deque needs to move
elements around (of course, if you never do any inserts/deletes to the
middle of the deque, they're not being copied anyway).

See www.boost.org if you're not familiar with Boost. Boost 1.30.2 works
very well with VC7.1.

-cd


Dan said:
Carl,

Do you have a suggestion of a way to obtain the same functionallity
this construct affords me.

I use this many places in quite a few codes.

An example is a matrix class where the "current" or "this" matrix is
the matrix sum of all the matrices in the deque, each is in-turn the
sum of all the matrices in its deque and so on. If the deque is
emplty then data stored in the matrix class is used to define the
"this" matrix. In the case I am describing I am using the BOOST
UBLAS library to actually store the matrices and do the matrix
multiplication.

Again, this is just one example. I do this type of things many
places, eg.

-Storing temperature dependant material properties where the values
at the root class object contains values interpolated for a given
temperature between the appropriate material properties in listed in
the deque for specific termperatures.

-Parsing files where each "card" (I'm starting to show my age) class
contains a deque of other "cards" in the file based on keyword,
subkeywords, etc. Feed the head of the class "tree" the heiarchial
keywords and it parses and sorts an appropraitly formatted file.

You get the idea. All these and more have been working fine for
years now.

Any design ideas would be appreciated. Right now my boss is not
happy that all the code I have written using this flawed design is
now broken so I would like to figure out a good fix fast.

Thanks for your response
Dan

"Carl Daniel [VC++ MVP]"
This is not legal C++ - it's illegal to instantiate any standard
library class on an incomplete type.


Better get busy re-writing.

-cd
 
D

Dan Trowbridge

Carl,

Well thanks for the help. Using pointers is the way I use to do it but, as
you know by your suggestion about using boost::shared_pointer, there is
quite a bit of overhead. To force you to use pointers seems to go against
the idea behind some of the best things about C++, e.g. inheritance, virtual
functions, abstraction, the whole generic programming thought. It seems
like an inconsistency.

It is a shame that what I was doing doesn't work now (or really shouldn't
have worked all along). I wonder why the standard committee disallowed
(never allowed) it. It obviously works (or can work) - I have used it for a
long time and the VS C++ 6.0 compiler didn't complain about it. I guess
ignorance is NOT bliss. Oh well, I will leave that to smarter people than
me. Enough lamenting - time to get coding.

Thanks again for your prompt and helpful response.
Dan

Carl Daniel said:
Dan -

Normally the approach would be to store pointers instead of class instances.
You might try replacing std::deque<Foo> with
std::deque<boost::shared_ptr<Foo> >. That way all of the memory management
will be taken care of for you (as it is with the non-portable solution
you're using now). The resulting code will likely be more efficient too,
since your Foo's won't have to be copied when the deque needs to move
elements around (of course, if you never do any inserts/deletes to the
middle of the deque, they're not being copied anyway).

See www.boost.org if you're not familiar with Boost. Boost 1.30.2 works
very well with VC7.1.

-cd


Dan said:
Carl,

Do you have a suggestion of a way to obtain the same functionallity
this construct affords me.

I use this many places in quite a few codes.

An example is a matrix class where the "current" or "this" matrix is
the matrix sum of all the matrices in the deque, each is in-turn the
sum of all the matrices in its deque and so on. If the deque is
emplty then data stored in the matrix class is used to define the
"this" matrix. In the case I am describing I am using the BOOST
UBLAS library to actually store the matrices and do the matrix
multiplication.

Again, this is just one example. I do this type of things many
places, eg.

-Storing temperature dependant material properties where the values
at the root class object contains values interpolated for a given
temperature between the appropriate material properties in listed in
the deque for specific termperatures.

-Parsing files where each "card" (I'm starting to show my age) class
contains a deque of other "cards" in the file based on keyword,
subkeywords, etc. Feed the head of the class "tree" the heiarchial
keywords and it parses and sorts an appropraitly formatted file.

You get the idea. All these and more have been working fine for
years now.

Any design ideas would be appreciated. Right now my boss is not
happy that all the code I have written using this flawed design is
now broken so I would like to figure out a good fix fast.

Thanks for your response
Dan

"Carl Daniel [VC++ MVP]"
Dan Trowbridge wrote:
He everyone,

I am just getting started with .NET and I am having a porting
problem. I get and error in code that lookssomething like this
(really
stripped down but you get the idea)...

class dt
{
std::deque< class dt > dtdq;
};

That is a class that contains a deque of class objects of it's own
type.

This is not legal C++ - it's illegal to instantiate any standard
library class on an incomplete type.


Is there work-around someone knows about? I use this design
feature in a lot of code I developed in VC6 and it represents a
major
re-write if I can't figure away around this.

Better get busy re-writing.

-cd
 
K

Ken Alverson

Dan Trowbridge said:
Well thanks for the help. Using pointers is the way I use to do it but, as
you know by your suggestion about using boost::shared_pointer, there is
quite a bit of overhead.

The only overhead of a boost::shared_pointer versus a standard pointer should
be when you are creating/copying/destroying them, which should not happen
often in your deque.

Of course, both shared pointers and standard pointers will put you one level
of indirection further from your data. That will involve some overhead, but
I'd hesitate to call it "quite a bit", unless the type being pointed to is
pretty simple.

Ken
 
H

Hendrik Schober

Dan Trowbridge said:
Carl,

Well thanks for the help. Using pointers is the way I use to do it but, as
you know by your suggestion about using boost::shared_pointer, there is
quite a bit of overhead. To force you to use pointers seems to go against
the idea behind some of the best things about C++, e.g. inheritance, virtual
functions, abstraction, the whole generic programming thought. It seems
like an inconsistency.

I don't see how to get rid of the overhead
for 'new'/'delete'. However, you might be
able to leave the code that uses these
containers unchanged, if you crate a kind
of "reference class". Something like this:

template< typename T >
class reference {
public:
reference(T* p) : ptr_(p) {assert(ptr_);}
operator T&() {return *ptr_);
operator const T&() const {return *ptr_);
private:
T* ptr_;
};
It is a shame that what I was doing doesn't work now (or really shouldn't
have worked all along). I wonder why the standard committee disallowed
(never allowed) it. It obviously works (or can work) - I have used it for a
long time and the VS C++ 6.0 compiler didn't complain about it. I guess
ignorance is NOT bliss. Oh well, I will leave that to smarter people than
me. Enough lamenting - time to get coding.

I wouldn't know the details behind that
restriction. But you should consider that
VC6 might only have gotten away with this
because it is so horribly broken when it
comes to templates. It might just not have
implemented some feature (correctly),
which wouldn't work with this code.
Thanks again for your prompt and helpful response.
Dan
[...]

Schobi

--
(e-mail address removed) is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
 

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

Top