Question

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

Was it helpful?

Solution

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;

OTHER TIPS

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 would just be dubious baggage hanging around waiting to fail when somebody went to use it with a value determined at run time. People looking at the interface without looking over the entire implementation would 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 (i.e. as a run-time parameter rather than a template parameter) then that's fine and dandy, but if the compiler had to instantiate 100,000 versions of f() each specialising CAT<>s with successive values of i/N the executable program size could become huge (optimisation - if enabled - may mitigate that).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top