Использовать параметр шаблона в директиве препроцессора? - PullRequest
7 голосов
/ 25 мая 2010

Можно ли использовать параметр шаблона нетипичного константы в директиве препроцессора? Вот что я имею в виду:

template <int DING>
struct Foo
{
    enum { DOO = DING };
};

template <typename T>
struct Blah
{
    void DoIt()
    {
        #if (T::DOO & 0x010)

        // some code here

        #endif
    }
};

Когда я пытаюсь это сделать с чем-то вроде Blah<Foo<0xFFFF>>, VC ​​++ 2010 жалуется на несоответствующие скобки в строке, где мы пытаемся использовать #if. Я предполагаю, что препроцессор действительно ничего не знает о шаблонах, и такого рода вещи просто не относятся к его сфере. Что сказать?

Ответы [ 3 ]

11 голосов
/ 25 мая 2010

Нет, это невозможно.Препроцессор довольно тупой и не знает структуры вашей программы.Если T::Doo не определен в препроцессоре (и это не может быть из-за ::), он не может вычислить это выражение и завершится ошибкой.

Однако вы можете положиться на компилятор дляСделайте разумную вещь для вас:

        if (T::Doo & 0x010) {
            // some code here
        }

Постоянные выражения и мертвые ветви оптимизируются даже при более низких настройках оптимизации, так что вы можете безопасно делать это без каких-либо накладных расходов во время выполнения.

2 голосов
/ 25 мая 2010

то, какие элементы доступны в T, зависит от того, какие биты установлены в T::DOO

Мне кажется, что T::DOO действует как идентификатор подкласса. Поэтому я думаю, что ваши Foo и связанные классы должны быть подклассами класса, который гарантирует, что DOO определен.

Ключ: почему вы должны использовать битовое поле?

1 голос
/ 03 сентября 2010

Не уверен, относится ли это к вашей ситуации, но есть возможность изолировать разные случаи с помощью шаблонных классов. Например: (используя измененную версию вашего кода сверху)

template <typename T, int N>
struct Blah
{
    void DoIt()
    {
        // normal DoIt() code
    }
};

template <typename T>
struct Blah<T,5>
{
    void DoIt()
    {
        // special DoIt() code for only when N==5
    }
};
...