static_assert не скомпилируется, хотя шаблонная функция нигде не вызывается

Я использую g ++ 4.6.3 (в настоящее время это пакет по умолчанию для ubuntu 12.04) с флагом c ++ 0x, и я натыкаюсь на это:

template <typename T>
inline T getValue(AnObject&)
{
static_assert(false , "this function has to be implemented for desired type");
}

с ошибкой компиляции:

static_assertion failed "this function has to be implemented for the desired type"

хотя я еще нигде не вызываю эту функцию.

Это ошибка G ++? Эта функция не должна создаваться только в том случае, если она вызывается где-то в коде.

29

Решение

Это потому, что условие никак не зависит от параметров шаблона. Следовательно, компилятор может оценить его еще до создания экземпляра этого шаблона и выдает соответствующее сообщение об ошибке компиляции, если это дает оценка false,

Другими словами, это не ошибка. Хотя многие вещи могут быть проверены только после создания экземпляра шаблона, существуют другие проверки достоверности, которые компилятор может выполнить даже раньше. Вот почему в C ++, например, есть двухфазный поиск имен. Компилятор просто пытается помочь вам найти ошибки, которые могут возникнуть на 100%.

21

Другие решения

Стандарт говорит в [temp.res] / 8

Не должно быть выдано никакой диагностики для определения шаблона, для которого может быть сформирована действительная специализация. Если для определения шаблона не может быть сгенерировано никакой действительной специализации, и этот шаблон не создан, определение шаблона неверно, диагностика не требуется. … [ Заметка: Если шаблон создан, ошибки будут диагностированы в соответствии с другими
правила в этом стандарте. Именно тогда, когда эти ошибки диагностируются, возникает проблема качества реализации. — конец примечания]

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

Вы можете заставить его работать так:

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> будет создан, и статическое утверждение все равно не будет выполнено, как хотелось бы.

46

Это действительно комментарий, но требуется пример кода.

Священный стандарт формулировка 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, что подчеркивает вопрос.

я считать ответ заключается в том, что g ++ верен, а Visual C ++ 11.0, который не приводит к ошибке компиляции, неверен, но мне было бы сложно дать соответствующий анализ в терминах стихов Священного Стандарта.

Практическим следствием разницы в компиляторе является то, что в настоящее время вы не можете полагаться на поведение.

3
По вопросам рекламы [email protected]