Я обнаружил случай, когда выражение внутри decltype обрабатывается успешно, в то время как такое же выражение вне decltype дает ошибку: посмотреть на Godbolt.

Я проверяю, есть ли перегрузка вывода в поток для данного типа (operator <<) - с помощью decltype и свойств типа. Но для libstdc ++ из GCC <7 decltype возвращает правильный тип даже в тех случаях, когда такой перегрузки нет.

Пробовал Clang с libc ++ - такой проблемы нет. Пробовал GCC 7.1 - без проблем. Но если я попробую GCC <7 или Clang с libstdc ++ из GCC <7 - возникнет проблема.

В принципе:

class Foo {};

...

decltype(std::declval<std::ostringstream>() << std::declval<Foo>()) // gives std::ostringstream&

...

Foo foo;
std::ostringstream out;
out << foo; // gives an error (as it should, there is no overload for Foo)

Итак, почему это происходит, что не так с libstdc ++?

0
Alexander Morozov 5 Янв 2018 в 11:23

1 ответ

Лучший ответ
std::declval<std::ostringstream&>() << std::declval<T const &>()
//                             ^                     ^^^^^^^^

Категории значений имеют значение. Вы тестируете возможность передавать lvalue const T в lvalue ostringstream.

В исходном коде << преобразуется в до недавнего времени без ограничений << перегрузка для потоков rvalue. Без ограничения выражение всегда имеет правильный формат.

2
T.C. 5 Янв 2018 в 09:17