Solved

compile time initialization of template class within template class

Posted on 2009-04-03
7
499 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 40

Accepted Solution

by:
mrjoltcola earned 70 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 70 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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 30 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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
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 …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

739 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