Это потому, что это условие никак не зависит от параметров шаблона. Поэтому компилятор может оценить его еще до создания экземпляра этого шаблона и выдает соответствующее сообщение об ошибке компиляции, если оно дает оценку false
.
Другими словами, это не ошибка. Хотя многие вещи могут быть проверены только после создания экземпляра шаблона, существуют другие проверки достоверности, которые компилятор может выполнить даже раньше. Вот почему, например, C ++ имеет двухфазный поиск имен. Компилятор просто пытается помочь вам найти ошибки, которые на 100% могут возникнуть.
Это действительно комментарий, но для этого нужен пример кода.
Текст священного стандарта для static_assert
не ограничивает его действие на экземплярный код.
Однако код
template <typename T>
inline T getValue(int&)
{
typedef char blah[-1]; // Common C++03 static assert, no special semantics.
}
int main()
{}
также не удается скомпилировать с MinGW g ++ 4.7.2, что подчеркивает вопрос.
I think ответ заключается в том, что g ++ прав, и что Visual C ++ 11.0, который не создает ошибку компиляции для этого, неверен, но мне было бы трудно предоставить соответствующий анализ в терминах стихов Святого Стандарта.
Практическое следствие разница в компиляторе заключается в том, что в настоящее время вы не можете полагаться на поведение.
Стандарт говорит в [temp.res] / 8
Диагностика не должна выдаваться для определения шаблона, для которого может быть создана действительная специализация. Если для определения шаблона не может быть создана действительная специализация, и этот шаблон не создается, определение шаблона плохо сформировано, не требуется диагностика. ... [Примечание: Если экземпляр шаблона создается, ошибки будут диагностированы в соответствии с другими правилами настоящего стандарта. Точно, когда эти ошибки диагностируются, это проблема качества реализации. - примечание к концу]
blockquote>Невозможно создать экземпляр шаблона функции, который будет компилироваться, поэтому определение шаблона плохо сформировано и поэтому разрешен компилятор (но не обязательно), чтобы отклонить его, даже если он не создан.
Вы можете заставить его работать следующим образом:
template<typename T> struct foobar : std::false_type { }; template <typename T> inline T getValue(AnObject&) { static_assert( foobar<T>::value , "this function has to be implemented for desired type"); }
Теперь компилятор не может сразу отказаться от шаблона функции , поскольку до момента его создания он не знает, будет ли специализация
foobar
, которая имеетvalue == true
. При создании экземпляра соответствующая специализацияfoobar<T>
будет создана и статическое утверждение будет по-прежнему терпеть неудачу.