compile time initialization of template class within template class

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

forums_mpAsked:
Who is Participating?
 
mrjoltcolaConnect With a Mentor Commented:
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
 
forums_mpAuthor Commented:
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
 
mrjoltcolaConnect With a Mentor Commented:
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
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
forums_mpAuthor Commented:
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
 
forums_mpAuthor Commented:
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
 
mrjoltcolaCommented:
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
 
KimpanConnect With a Mentor Commented:
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
All Courses

From novice to tech pro — start learning today.