C ++ проверка времени компиляции с использованием шаблонов - PullRequest
2 голосов
/ 27 февраля 2011

У меня следующий код, взятый из современного дизайна C ++. В то время как я использую это, я получаю ошибку компиляции, я думаю, что недопустимый размер opearand. Можно ли указать, в чем проблема. Спасибо!

template<bool>
struct CompileTimeChecker {
    CompileTimeChecker(...);
};

template<>
struct CompileTimeChecker<false> {
};

#define STATIC_CHECK(expr, msg) \
{\
class ERROR_##msg {}; \
(void)sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg())));\
}

template <class To, class From>
To safe_reinterpret_cast(From from) {
    STATIC_CHECK(sizeof(From) <= sizeof(To), Destination_Type_Too_Narrow);
    return reinterpret_cast<To>(from);
}

int main(void)
{
    int a[20];
    void* somePointer = a;
    char c = safe_reinterpret_cast<int>(somePointer);
}

Ошибка:

d: \ technical \ c ++ study \ readparsing \ readparsing \ addressconv.cpp (29): ошибка C2066: приведение к типу функции недопустимо 1> d: \ technical \ c ++ study \ readparsing \ readparsing \ addressconv.cpp (37): см. Ссылку на создание экземпляра шаблона функции «To safe_reinterpret_cast (From)» во время компиляции 1> с 1> [ 1> To = int, 1> От = пусто * 1>] 1> d: \ technical \ c ++ study \ readparsing \ readparsing \ addressconv.cpp (29): ошибка C2070: 'CompileTimeChecker <__ formal> (safe_reinterpret_cast :: ERROR_Destination_Type_Too_Narrow (__cdecl *) (void))': недопустимая опера 1> с 1> [ 1> __formal = true 1>]

Ответы [ 2 ]

4 голосов
/ 27 февраля 2011

Еще один удар для самого неприятного разбора ...

sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg()))

Это то же самое, что и

class Foo {};
class Bar {};
sizeof(Foo((Var()));

, и Foo (Var) можно интерпретировать как тип (функция, принимающая (функция без аргумента, возвращающая Var) и возвращающая Foo), это так.

1 голос
/ 27 февраля 2011

Как указал AProgrammer, компилятор не проглатывает размер (void) sizeof. Я предлагаю удалить скобки из sizeof, например так:

(void)sizeof CompileTimeChecker<(expr) != 0>((ERROR_##msg()));\

Это, кажется, заставляет g ++ принять его и интерпретировать так, как это, вероятно, и предполагалось.

Если этот (пустой) sizeof продолжает доставлять вам неприятности, вы можете получить функцию статической проверки и без нее, например, инициализируя переменную CompileTimeChecker:

CompileTimeChecker<(expr) != 0> a((ERROR_##msg()));\
...