Improve company productivity with a Business Account.Sign Up

x
?
Solved

compile time initialization of template class within template class

Posted on 2009-04-03
7
Medium Priority
?
511 Views
Last Modified: 2012-05-06
I'd like to create an vector of the composite type sequence_of.  Within sequence_of there's a class controller.  The contoller class needs to instantiate at compile time iord_direct...  Microsoft .NET 2008 barfs (a window pops saying optimizing compiler has encountered a problem ..... tell microsoft etc. etc.) during compilation.  At issue:  How could I design the controller class such that I achieve the objective of being able to call a template class (iord_) within the template class (controller)?
# include <iostream>
# include <bitset>
# include <vector>
# include <string>
 
template <unsigned int size>
unsigned int iord_direct(unsigned int base, unsigned int offset);
 
// use this as example
template <>
unsigned int iord_direct<32>(unsigned int base, unsigned int offset) {
  //return __builtin_ldwio(__IO_CALC_ADDRESS_DYNAMIC(base, offset));
  return  0; 
}
 
template < typename UnsignedType > 
class controller 
{ 
  unsigned const size ; 
  unsigned const base ; 
  unsigned const offset ; 
 
  UnsignedType& a ; 
  //void get ( UnsignedType& a ) 
  //{
  //  UnsignedType xx = iord_direct < size > ( base, offset ) ; 
  //  a = xx ;
  //}
 // stuff 
public : 
  controller ( UnsignedType a_, unsigned size, unsigned base, unsigned offset ) 
  : a( a_) 
  , size   ( size ) 
  , base   ( base ) 
  , offset ( offset ) 
  {} 
  void get ( unsigned int ax ) 
  {
    UnsignedType xx = iord_direct < size > ( base, offset ) ;   //<<<<<E
    //a = xx ;
  }
}; 
 
 
struct sequence_of { 
  unsigned int mValue ; 
  controller < unsigned int > mwhatever; 
  sequence_of ( unsigned int size_, unsigned int base_addr_, unsigned int offset_  ) 
   : mValue    ( 0 ) 
   , mwhatever ( mValue, size_, base_addr_, offset_ ) 
  {} 
 
}; 
 
 
typedef std::vector < sequence_of* > SEQOF_VEC ; 
 
int main() { 
  SEQOF_VEC mSeqVec ; 
  int offset          = 0 ; 
  int const size      = 32;
  int const base_addr = 0x900000 ; 
  for ( int odx ( 0 ); odx < 30 ; ++odx ) { 
    mSeqVec.push_back ( new sequence_of ( size, base_addr,  offset  ) ) ; 
    offset += 2 ; 
  } 
  unsigned int zz = 4;
  mSeqVec [ 0 ]->mwhatever.get ( zz ) ;
 
 
}

Open in new window

0
Comment
Question by:forums_mp
  • 3
  • 3
7 Comments
 
LVL 40

Accepted Solution

by:
mrjoltcola earned 280 total points
ID: 24062133
Before looking at your code, did you install VS 2008 service pack 2? Sounds like the compiler had an internal problem with your code.

As far as your code, you have place where you are trying to instantiate a template using a non-constant integer expression.


// Template parameters must be types or constants (known at compile time). size is dynamic, so cannot be generated
// at compile time, which is a requirement for templates, by definition. A constant, for example, would be 42
// In your code, size is actually a member of the surrounding class, which is set in a constructor. The compiler won't
// know what size equals until runtime, and even then, it will be differnet for each object, so C++ cannot instantiate
// a template using "size"
 
  void get ( unsigned int ax )
  {
    UnsignedType xx = iord_direct < size > ( base, offset ) ;   //<<<<<E   CANNOT USE size, it is not constant
    //a = xx ;
  }

Open in new window

0
 

Author Comment

by:forums_mp
ID: 24062414
mrjoltcola:
Granted i'm away from my compiler rigth now, however, if I modified controller to account for size in the template argument list,  I still get an error from the compiler.  If memory serves the error is: 'illegal reference to non-static member' on base and offset..
# include <iostream>
# include <bitset>
# include <vector>
# include <string>
 
template <unsigned int size>
unsigned int iord_direct(unsigned int base, unsigned int offset);
 
// use this as example
template <>
unsigned int iord_direct<32>(unsigned int base, unsigned int offset) {
  //return __builtin_ldwio(__IO_CALC_ADDRESS_DYNAMIC(base, offset));
  return  0; 
}
 
template < typename UnsignedType, unsigned size > 
class controller 
{ 
  unsigned const base ; 
  unsigned const offset ; 
 
  UnsignedType& a ; 
  //void get ( UnsignedType& a ) 
  //{
  //  UnsignedType xx = iord_direct < size > ( base, offset ) ; 
  //  a = xx ;
  //}
 // stuff 
public : 
  controller ( UnsignedType a_, unsigned base, unsigned offset ) 
  : a( a_) 
  , base   ( base ) 
  , offset ( offset ) 
  {} 
  void get ( unsigned int ax ) 
  {
    UnsignedType xx = iord_direct < size > ( base, offset ) ;   //<<<<<E
    //a = xx ;
  }
}; 
 
 
struct sequence_of { 
  unsigned int mValue ; 
  controller < unsigned int, 32 > mwhatever; 
  sequence_of ( unsigned int base_addr_, unsigned int offset_  ) 
   : mValue    ( 0 ) 
   , mwhatever ( mValue, base_addr_, offset_ ) 
  {} 
 
}; 
 
 
typedef std::vector < sequence_of* > SEQOF_VEC ; 
 
int main() { 
  SEQOF_VEC mSeqVec ; 
  int offset          = 0 ; 
  int const base_addr = 0x900000 ; 
  for ( int odx ( 0 ); odx < 30 ; ++odx ) { 
    mSeqVec.push_back ( new sequence_of ( base_addr,  offset  ) ) ; 
    offset += 2 ; 
  } 
  unsigned int zz = 4;
  mSeqVec [ 0 ]->mwhatever.get ( zz ) ;
 
 
}

Open in new window

0
 
LVL 40

Assisted Solution

by:mrjoltcola
mrjoltcola earned 280 total points
ID: 24062454
The code you just posted compiles fine with no errors GCC/G++, though I don't know that it runs. Check back when you are at your compiler.

Also, FYI VS 2008 Service Pack 2 is avail, do you have it installed? I just thought of it since you had an internal compiler error.


0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Comment

by:forums_mp
ID: 24062900
mrjoltcola::
|| Also, FYI VS 2008 Service Pack 2 is avail, do you have it installed? I
Probably not but I'll check!
While I have the code here (it's a shame this laptop doesnt have a compiler on it): I recalled a handful of errors if I opted to make the get function static.  Not following why?
0
 

Author Comment

by:forums_mp
ID: 24065522
Apparently I didnt have service pack 2 installed.  Also tried a gcc compiler and the most recent version of the code worked.   What would be the workaround for a static get method?  The get method in the original source is static.  If i move to a non static alternative I get errors when I try to use std:cout on the object.

i.e
controller < unsigned int, 32 > mwhatever;
 std::cout << whatever << '\n';  //
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24065744
I don't understand what your code does, so I cannot comment on why you need static vs non-static. I can definitely say its nothing to do with using cout.

Basically inside a static method, you don't have an "object" (or "this") in context, so you cannot access any instance variables. You can only access other static members from a static method. Be aware of what static means in this context, its essentially a global storage, but with a class namespace and access control. It works like a global function. You can allocate instances of the class inside the static method, but the static method cannot use this-> anything.

0
 
LVL 5

Assisted Solution

by:Kimpan
Kimpan earned 120 total points
ID: 24066696
if iord_direct is supposed to take the byte- or bitsize of a specific type, you might use sizeof.

so get becomes if it is supposed to operate on UnsignedType:
  void get ( unsigned int ax )
    {
        UnsignedType xx = iord_direct < sizeof(UnsignedType) * 8 > ( base, offset ) ;   //<<<<<E
        //a = xx ;
    }

better would be to make iord_direct take a type

template<typename T>
unsigned int iord_direct(unsigned int base, unsigned int offset)
{
    enum { BITSIZE = sizeof(T) * 8  };  // compile-time operation
}
0

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

605 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question