Компилятор: 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()
являются недооцененными контекстами, поэтому я не уверен, в чем разница.
Это ошибка компилятора.
Решение вокруг этого заключается в использовании decltype()
вокруг выражения. И то и другое decltype()
а также typeid()
(в этом случае выражения non-polymorphic-glvalue) — это недооцененные контексты, которые не должны иметь значения, что и делает это ошибкой. С помощью decltype()
здесь действует как своего рода «буфер оцененного контекста», и как-то typeid()
нравится это лучше.
Что ж, пора связаться с TDM по этому поводу. Эта ошибка не является проблемой TDM, это ошибка ванили (спасибо ildjarn).
Других решений пока нет …