2010-10-21 1 views
8
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 

но я преобразовать я на константные 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("...") 

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

+0

Помните: много раз, когда вы получаете ошибки на одной строке, это много раз выше. Как показывает ответ Джеймса. – 2010-10-21 04:57:22

+0

Просто потому, что тип const не означает, что его значение есть. – GManNickG

+0

Повторяю: просто потому, что тип const не означает, что это значение. Вы можете сказать: 'f (rand());' или 'int i = rand()'. Просто притворство const на типе не означает вещь. – GManNickG

ответ

17

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

CAT<10> cat; 

или сделать iconst int:

const int i = 10; 
CAT<i> cat; 
+0

Спасибо вам, , но в некоторых случаях мне нужна неконстантная переменная, например: void f (const int j) { CAT cat; } – camino

+4

@camino: Тогда это не может быть шаблон. Шаблоны делают * типы *, типы - это конструкции времени компиляции. Если у вас есть более конкретный пример, мы могли бы помочь. – GManNickG

+0

Привет, GMan, я добавлю пример – camino

9

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

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 как аргумент конструктора (т. Е. Как параметр времени выполнения, а не параметр шаблона), тогда это нормально и dandy, но если компилятор должен был создать 100 000 версий f() каждый из CAT<> s с последовательными значениями i/N размер исполняемой программы может стать огромным (оптимизация - если включена - может смягчить это).

Смежные вопросы