Макросы и шаблоны препроцессора C ++ Constant - PullRequest
3 голосов
/ 16 октября 2010

Итак, скажем, у меня есть следующий очень простой макрос и немного кода для его вывода:

#define SIMPLEHASH(STRING) STRING[1] + STRING[2] + STRING[3]
std::cout <<  SIMPLEHASH("Blah");

Это выводит 309, и если вы просматриваете сборку, вы можете увидеть:

00131094  mov         ecx,dword ptr [__imp_std::cout (132050h)] 
0013109A  push        135h 
0013109F  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (13203Ch)] 

Где 135h хорошо переводится в 309 знаков после запятой. Все было скомпилировано в константу.


Теперь, скажем, у вас есть шаблонный класс как таковой:

template<int X> class Printer{
public:
 void Print(){
  std::cout << X;
 }
};

Тогда следующее будет приятно печатать число 32:

Printer<32> p;
p.Print();

Обе эти вещи работают по отдельности, проблема возникает, когда вы пытаетесь объединить их:

#define SIMPLEHASH(STRING) STRING[1] + STRING[2] + STRING[3]
 Printer<SIMPLEHASH("Blah")> p;
 p.Print();

В визуальной студии это дает:

1>. \ ShiftCompare.cpp (187): ошибка C2975: «X»: недопустимый аргумент шаблона для «Printer», ожидаемое постоянное выражение времени компиляции
1>. \ ShiftCompare.cpp (127): см. Объявление 'X'

Несмотря на то, что SIMPLEHASH("Blah") можно уменьшить до константы во время компиляции, как видно из первого примера.

Итак, что дает, есть ли способ сказать компилятору "сначала оценить это"? естественным образом макросы шаблонов "перед" в оценке препроцессора?

Кто-нибудь видит, как я могу заставить этих двоих работать вместе?

1 Ответ

5 голосов
/ 16 октября 2010

Макросы оцениваются до того, как источник полностью проанализирован, а предварительная обработка не имеет ничего общего с шаблонами.

Проблема в том, что аргумент шаблона, с которым вы создаете экземпляр Printer, должен быть константным выражением, и вы не можете использовать строковый литерал в константном выражении.

...