2016-10-12 11 views
3

Я пытаюсь использовать статическое утверждение pre-C++ 11. Я нашел this и this вопрос, но почему-то я не могу получить его работы:Почему это статическое утверждение не работает?

#define STATIC_ASSERT(x) \ 
    do { \ 
     const static char dummy[(x)?1:-1] = {0};\ 
    } while(0) 

struct bar { 
    int value; 
    template<typename T> void setValue(T x); 
}; 
template<typename T> void bar::setValue(T x) { STATIC_ASSERT(1==0); } 
template<> void bar::setValue(int x) { value = x;} 

int main(){ 
    bar b; 
    int c = 1; 
    b.setValue(c);  
} 

результаты Компиляция (ССАГПЗ) в

error: size of array 'dummy' is negative

Я ожидал бы эту ошибку apprear только если я позвоню setValue ни с чем кроме int. Я также пробовал другие предлагаемые решения, но с более или менее одинаковым результатом: ошибка существует, даже если я не создаю экземпляр шаблона ни с чем иным, кроме int. Что я делаю не так?

+0

Просто интересно, вы знаете, вы не должны использовать шаблон вообще в таком случае, а просто записать его с 'int' типа? (Это все еще интересный вопрос и ответ по образовательным причинам, но я надеюсь, что ваше реальное использование не так тривиально :)). – Ped7g

+0

@ Ped7g хорошо, на самом деле мое реальное использование так же тривиально, как пример. Я хочу абсолютно убедиться, что функция вызывается с параметром правильного типа, и преобразование не происходит. Является ли это хорошим подходом или нет, я еще не уверен, но это не обсуждение здесь. Я поставлю его на codereview ... – user463035818

+0

найти ключевое слово explict – UKMonkey

ответ

7

Если шаблон недействителен для каждого экземпляра, то программа плохо сформирована, не требуется диагностика. Таким образом, GCC совершенно справедлив в том, что вы здесь делаете ошибку, поскольку основной шаблон для setValue недействителен независимо от аргумента шаблона.

Способ решения этой проблемы состоит в том, чтобы сделать выражение STATIC_ASSERT зависимым от параметра шаблона. Одним из вариантов является сделать класс dependent_false шаблон, как это:

template <typename T> struct dependent_false 
{ const static bool value = false; }; 

template<typename T> void bar::setValue(T x) 
{ STATIC_ASSERT(dependent_false<T>::value); } 
+0

«Если шаблон недействителен для каждого экземпляра, значит, программа плохо сформирована», даже если есть специализация, которая не плохо сформирована? – user463035818

+1

@ tobi303 Yep ... – TartanLlama

+0

ОК, понял, но немного странно, что ваш хак работает. Если компилятор будет «достаточно умным», он все равно поймет, что шаблон неформатирован для любого T – user463035818