Кланг компилирует, gcc нет: https://godbolt.org/z/Y17o4oGbr
Кто прав, как обосновать? =)
Жусть. Кажется, что прав всё-таки gcc. Сомнительно, что этот decltype на что-то влияет
Зачем-то много всего накручено, это то же, что и: template <typename T, typename... Ts> void foo() { } template <typename T> void foo() { } int main() { foo<int>(); } Имхо прав GCC.
А там случаем не надо бы this везде добавить?
Как тут уже догадались, если поставить this (или убрать class) то оба справляются. Неужели оба в этом случае не правы?
А если убрать struct и убрать decltype, то оба не справляются, этот decltype очень нужен, он SFINAE-case делает =)
Ну тогда понятно, что для пустого параметр пака не сможет вывестись тип шаблона в decltype. Занятный пример. Без класса тогда можно так записать: template <typename T> void foo() { } template <typename T, typename... Ts> auto foo() -> decltype(foo<Ts...>()) { } int main() { foo<int>(); }
Я не мог не проверить. https://asciinema.org/a/HyhEhtqOPz6FGJeZxwW6lfcXI
g++ же надо... Ну и потом зачем такие ужасы когда есть годболт?
Мне gcc в termux не воткнуть. годболт неудобен с телефона
Прав Clang. Пример сводится к https://godbolt.org/z/qxbxvfKEs struct S { template <typename> void /* #1 */ as(); template <typename, typename... Ts> auto /* #2 */ as() -> decltype(as<Ts...>()); }; void test() { S{}.as<short, int, long>(); } который GCC почему-то компилирует, считая после подстановки trailing-return-type #2, что мн-во overloading candidates для as это все ф-и класса, включая саму перегрузку #2. На самом деле мн-во кандидатов должно включать в себя только то что объявлено до #2, т.е только #1 в нашем случае.
Очень красивая редукция, мои поздравления )) Действительно, дело в том: 1. Где кончается полное объявление 2. Нужно ли оно для набора в множество кандидатов
Но почему оно не должно включать само себя? Разве рекурсивный вызов самого себя не надо рассматривать?
Хотя да, как тогда вообще закончить подобную рекурсию, логично
Чтобы писать auto f() -> decltype(f()); было неповадно
Но что если у нас f() есть в глобальном пространстве имён?) Соответственно у нас должен инстанцироваться вариант от глобального f() (он ведь валиден?), но вариант с подстановкой себя - ошибка (но SFINAE и поэтому ок).
Обсуждают сегодня