Подтвердить что ты не робот

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

Я использую g++ 4.6.3 (текущий пакет по умолчанию для ubuntu 12.04) с флагом С++ 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++? Не следует ли устанавливать эту функцию только в том случае, если она называется где-то в коде.

4b9b3361

Ответ 1

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

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

Ответ 2

Стандарт говорит в [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> будет создана и статическое утверждение будет по-прежнему терпеть неудачу.

Ответ 3

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

Священная стандартная формулировка для 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 С++ 11.0, который не создает ошибку компиляции для этого, неверен, но мне было бы трудно предоставить соответствующий анализ с точки зрения Священного стандарта стихи.

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