views:

65

answers:

2

Hi ,

template < int >  
  class CAT  
  {};  

  int main()  
  {  
     int i=10;  
     CAT<(const int)i> cat;  
     return 0; //here I got error: ‘i’ cannot appear in a constant-expression  
  }  

even

   int i=10;  
   const int j=i;  
   CAT<j> cat; //this still can not work

but I have convert i to const int ,why compiler still report error ?
my platform is ubuntu,gcc version 4.4.3

Thanks,

==============

Thanks all for your input, but in some cases,I need a non-const variable ,

for example:

  //alloperations.h   
  enum OPERATIONS  
  {  
       GETPAGE_FROM_WEBSITE1,  
       GETPAGE_FROM_WEBSITE2,  
       ....  
  };  


  template< OPERATIONS op >  
  class CHandlerPara  
  {  
       static string parameters1;         
       static string parameters2;         
       ....  
       static void resultHandler();  
  };     


  //for different operations,we need a different parameter, to achieve this  
  //we specified parameters inside CHandler, for  example  

  template<>  
  string CHandlerPara< GETPAGE_FROM_WEBSITE1 >::parameters1("&userid=?&info=?..")  

  template<>  
  string CHandlerPara< GETPAGE_FROM_WEBSITE1 >::parameters2("...")  

other module will using this template to get corresponding parameter
and maybe specilize the resultHandler function for a special behavior

+10  A: 

A non-type template argument needs to be a compile-time constant. Casting an int to a const int does not make it a compile-time constant. You either need to use 10 directly:

CAT<10> cat;

or make i a const int:

const int i = 10;
CAT<i> cat;
James McNellis
Thanks you your input, but in some cases,I need a non-const variable ,for example: void f(const int j) { CAT<j> cat; }
camino
@camino: Then it can't be a template. Templates make *types*, types are compile-time constructs. If you have a more concrete example, we could help.
GMan
Hi GMan,I have add the example
camino
@camino: It's not too concrete though. I still don't know what you're trying to *do*.
GMan
+1  A: 

It's important to understand what templates are: they're code that's reinstantiated for each combination of specific template types or values.

void f(const int j) { CAT<j> cat; } 

This is asking f to create a different type of CAT<> each time it runs, but templates must be resolved at compile time. Conceptually, the compiler might cope if you only ever called f() with values it could work out at compile time, but if you're planning to that then you can simply write:

template <int N>
void f() { CAT<N> cat; }

This will generate multiple f() functions that create custom CAT<> instantiations. The C++ Standard doesn't even ask the compiler to tentatively accept the void f(const int j) version - it's just dubious baggage hanging around waiting to fail when somebody goes to use it with a value determined at run time. People looking at the interface without looking over the entire implementation expect f() to be callable with such run-time values - e.g. f(atoi(argv[2])). Or, they might put for (int i = 0; i < 100000; ++i) f(i). If f() takes an int at run-time, and say gives it to CAT as a constructor argument, then that's fine and dandy, but if the compiler had to instantiate 100,000 versions of f() each specialised CAT<>s with successive values of i/N, the executable program size would become huge.

Tony