получил "не может появляться в константном выражении" при использовании шаблона - PullRequest
9 голосов
/ 21 октября 2010
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  
  }  

даже

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

но я преобразовал i в const int, почему компилятор все еще сообщает об ошибке?
моя платформа - Ubuntu, версия gcc 4.4.3

Спасибо,

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

Спасибо всем за ваш вклад, но в некоторых случаях мне нужна неконстантная переменная,

например:

  //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("...")  

другой модуль будет использовать этот шаблон для получения соответствующего параметра
и, возможно, специфицировать функцию resultHandler для специального поведения

Ответы [ 2 ]

18 голосов
/ 21 октября 2010

Нетипизированный аргумент шаблона должен быть константой времени компиляции.Приведение int к const int не делает его постоянной времени компиляции.Вам либо нужно использовать 10 напрямую:

CAT<10> cat;

, либо сделать i a const int:

const int i = 10;
CAT<i> cat;
9 голосов
/ 21 октября 2010

Важно понимать, что такое шаблоны: это код, который заново создается для каждой комбинации определенных типов шаблонов или значений.

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

Это просит f создавать новый тип CAT<> при каждом запуске, но шаблоны должны быть разрешены во время компиляции. Концептуально, компилятор мог бы справиться, если бы вы только когда-либо вызывали f() со значениями, с которыми он мог бы работать во время компиляции, но если вы планируете это сделать, вы можете просто написать:

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

Эта будет генерировать несколько f() функций, которые создают пользовательские CAT <> экземпляры.

Стандарт C ++ даже не требует, чтобы компилятор предварительно принял версию void f(const int j) - это был бы просто сомнительный багаж, зависший в ожидании сбоя, когда кто-то использовал его со значением, определенным во время выполнения. Люди, которые смотрят на интерфейс, не просматривая всю реализацию, ожидают, что f() будет вызываться с такими значениями времени выполнения - например, f(atoi(argv[2])). Или они могут поставить for (int i = 0; i < 100000; ++i) f(i). Если f() принимает int во время выполнения и, скажем, передает его CAT в качестве аргумента конструктора (то есть в качестве параметра времени выполнения, а не параметра шаблона), то это нормально, но если компилятор пришлось создать 100 000 версий f(), каждая из которых специализировалась на CAT<> с последовательными значениями i/N, размер исполняемой программы мог бы стать огромным (оптимизация - если она включена - может уменьшить это).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...