Те, що я розповідаю нижче (під СТАРИМ ПОСТ ), повинно бути істинним, але актуальною проблемою є те, що SFINAE використовується неправильно, отже, я вже не впевнений, що це помилка в gcc.
Декларація псевдоніму завжди має бути успішною, ви не можете там SFINAE, оскільки це не декларація класу чи функції чи спеціалізації (це має сенс, оскільки ви не можете спеціалізувати псевдоніми). Якщо декларація псевдоніму не вдається, програма неправильно формується. Отже, компілятор може припустити, що він ніколи не прийде до того, що декларація псевдоніму не вдасться, поки ви не змусите його створити такий шаблон.
Отже, компілятору цілком прийнятно думати, що sfinae_v_t<T,...>
це завжди T
, оскільки це станеться, коли програма не буде сформована. Звідси видно, що у всіх випадках, коли програма не є сформованою, часткова спеціалізація не спеціалізується, і як така вона скаже вам, що це неправильно формується. (Ось що робить кланг).
Я не думаю, що компілятор змушений це робити. А якщо це не так, і просто думає «Добре, sfinae_v_t
якийсь тип, що завгодно.», То не очевидно, що це передекларація. Тому я думаю, поки ми не створимо один із них, немає нічого поганого в тому, щоб не кинути помилку.
Але коли ми інстанціонуємо це, то повинна бути або проблема в тому, що у нас є передекларація, або в тому, що програма неправильно формується через std::enable_if
, залежно від аргументу шаблону. GCC має забрати хоча б одну з них, але не робить жодної.
Це також абсолютно не стосується більш легкого прикладу без std::enable_if
. Тож я все ще думаю, що це помилка в GCC, але я достатньо вражений, що більше не можу цього сказати з певністю. Я б просто сказав, що хтось повинен повідомити про це як про помилку і нехай люди з gcc подумають про це.
СТАРИЙ ПОСТ
Це помилка в gcc. Стандарт дає нам правила перетворення шаблону класу в шаблони функцій. Шаблон одного класу є більш спеціалізованим, ніж інший, якщо його функція приходить до впорядкування шаблону часткової функції.
Я створив тут функції і тепер gcc стверджує, що викликати їх неоднозначно, отже, слід було б також сказати, що шаблони класів однаково вказані.
Примітка: уважно читаючи стандарт, компілятор в моїй голові погоджується з кланг.