То, что я расскажу ниже (под OLD POST ), должно быть в некоторой степени правдой, но реальная проблема в том, что SFINAE используется неправильно, поэтому я больше не уверен, что это ошибка в gcc.
Объявление псевдонима всегда должно быть успешным, вы не можете использовать SFINAE, поскольку это не объявление класса или функции или специализации (это имеет смысл, поскольку вы не можете специализировать псевдонимы). Если объявление псевдонима не удается, программа некорректна. Следовательно, компилятор может предположить, что он никогда не придет к случаю, что объявление псевдонима не будет успешным, пока вы не заставите его создать такой шаблон.
Следовательно, для компилятора вполне приемлемо думать, что sfinae_v_t<T,...>
это всегда T
, так как это произойдет, когда программа не будет плохо сформирована. Следовательно, он увидит, что во всех случаях, когда программа не является плохо сформированной, частичная специализация не специализируется, и как таковая она скажет вам, что это неправильно сформировано. (Это то, что делает Clang).
Я не думаю, что компилятор вынужден это делать. И если это не так, и просто думает: «Хорошо, sfinae_v_t
это какой-то тип, что угодно.», Тогда не очевидно, что это повторная декларация. Поэтому я думаю, что пока мы не создадим один из них, нет ничего плохого в том, чтобы не выдавать ошибку.
Но когда мы создаем его экземпляр, должна возникать проблема, связанная с тем, что у нас есть переопределение, или из-за неправильной формы программы std::enable_if
, в зависимости от аргумента шаблона. GCC должен подобрать хотя бы один из них, но не делает ни того, ни другого.
Это также абсолютно не относится к более легкому примеру без std::enable_if
. Поэтому я все еще думаю, что это ошибка в GCC, но я достаточно ошеломлен, что не могу с уверенностью сказать это. Я бы сказал, что кто-то должен сообщить об этом как об ошибке и позволить людям из gcc подумать об этом.
СТАРЫЙ ПОСТ
Это ошибка в GCC. Стандарт дает нам правила для преобразования шаблона класса в шаблоны функций. Один шаблон класса более специализирован, чем другой, если его функция предшествует другой в упорядочении шаблона частичной функции.
Я создал функции здесь, и теперь gcc заявляет, что их вызов неоднозначен, поэтому также следует сказать, что шаблоны классов заданы одинаково.
Примечание: читая стандарт внимательно, компилятор в моей голове согласен с clang.