BOOST_STATIC_ASSERT(sizeof(T) == 0);
не допускается сбой до тех пор, пока не будет создан экземпляр шаблона, поэтому я бы просто сделал это. Вы правы, что BOOST_STATIC_ASSERT(false);
срабатывает каждый раз.
Причина этого связана с поиском двухфазного имени. По сути, это следующее: когда шаблон компилируется, он компилируется дважды. Первый раз, когда компилятор видит шаблон, он компилирует все , кроме выражений, зависящих от параметров шаблона, и вторая компиляция происходит, когда параметр шаблона известен, полностью компилируя экземпляр.
Вот почему BOOST_STATIC_ASSERT(false);
всегда будет терпеть неудачу: здесь ничего не зависит, и утверждение обрабатывается немедленно, как если бы функция вообще не была шаблоном. (Обратите внимание, что MSVC не реализует двухфазный поиск, поэтому это неправильно при создании экземпляра.) Наоборот, потому что T
является зависимым (§14.6.2.1), BOOST_STATIC_ASSERT(sizeof(T) == 0);
является зависимым и не может быть проверяется, пока не будет создан экземпляр шаблона. (Где это всегда будет терпеть неудачу.)
Если компилятор попытается быть вдумчивым и потерпит неудачу раньше времени, он будет несоответствующим. Вы полагаете, что сможете положиться на это. Тем не менее, если страх возобладает над вами, это просто для действительно заставить его подождать:
BOOST_STATIC_ASSERT(sizeof(typename T::please_use_specializations) == 0);
Это гарантированно приведет к сбою, и компилятору не удастся правильно «умно» выйти из строя раньше времени.