Невозможно использовать declval в typeid для TDM-GCC

Компилятор: TDM-GCC-5.1.0 (разматывание SJLJ)

Я играл с declval и я заметил, что не смог использовать его в контексте, где он должен работать: в качестве аргумента typeid(),

В следующем коде я использую declval для одного из его основных случаев использования: для получения возвращаемого типа метода без прохождения экземпляра. Я получаю сообщение об ошибке static_assert declval, но это должно быть невозможно, потому что typeid() не оценивает его аргумент в этом случае:

#include <typeinfo>
#include <utility>

struct Foo
{
    int func();
};

int main()
{
    typeid(std::declval<Foo>().func());
}

Это не компилируется для меня (при компиляции с -std=c++14). Мое единственное предположение, что либо я обнаружил ошибку компилятора, либо я сделал что-то явно неправильное, и я не вижу этого. Если это последнее, мои извинения.

РЕДАКТИРОВАТЬ: Спасибо ildjarn за помощь, решение состоит в том, чтобы использовать decltype, поэтому последняя строка кода становится:

typeid(decltype(std::declval<Foo>().func()));

и это прекрасно работает. Тем не менее, теперь мой вопрос становится: как получилось? И то и другое typeid() а также decltype() являются недооцененными контекстами, поэтому я не уверен, в чем разница.

1 ответ

Решение

Это ошибка компилятора.

Решение вокруг этого заключается в использовании decltype() вокруг выражения. И то и другое decltype() а также typeid() (в этом случае выражения non-polymorphic-glvalue) - это недооцененные контексты, которые не должны иметь значения, что и делает это ошибкой. С помощью decltype() здесь действует как своего рода "буфер оцененного контекста", и как-то typeid() нравится это лучше.

Что ж, пора связаться с TDM по этому поводу. Эта ошибка не является проблемой TDM, это ошибка ванили (спасибо ildjarn).

Другие вопросы по тегам