Как P0522R0 разбивает код?
Сегодня я читал страницу поддержки С++ 17 для clang. Я заметил что-то странное. Параметр "Параметры шаблона шаблона сопоставления для совместимых аргументов" (P0522R0) отмечен как частичный, потому что он должен быть активирован с помощью переключателя. Их примечание говорит:
Несмотря на то, что это разрешение отчета об ошибке, эта функция отключена по умолчанию во всех языковых версиях и может быть включена явно с помощью флагов -frelaxed-template-template-args в Clang 4. Изменения в стандарте отсутствуют соответствующее изменение для частичного упорядочения шаблонов, что приводит к ошибкам неоднозначности для разумного и ранее действующего кода. Ожидается, что этот вопрос будет исправлен в ближайшее время.
Какие конструкторы ломаются, когда эта функция активирована? Почему он может сломать код и как?
Ответы
Ответ 1
У вас может быть такой код:
template<template<typename> typename>
struct Foo {};
template<typename, typename = void>
struct Bar {};
Foo<Bar> unused;
Без разрешения дефекта unused
будет плохо сформирован, потому что foo
принимает шаблон только с одним параметром шаблона, а не с двумя. Если вы полагаетесь на это (возможно, для SFINAE):
template<template<typename> typename>
void foo();
template<template<typename, typename> typename>
void foo();
template<typename, typename = void>
struct Bar {};
int main() {
foo<Bar>(); // ambiguous after resolution!
}
Тогда вызов не получится! Проблема в том, что не было соответствующего изменения частичного упорядочения, и поэтому обе функции-кандидаты имеют одинаковую жизнеспособность, а вызов неоднозначен.
Ответ 2
Более распространенный сценарий - это когда некоторый код хочет проверить аргументы шаблона с помощью набора частичных специализаций, например:
template<class> struct Foo;
template<template<class> class X, class T>
struct Foo<X<T>> { /* ... */ };
template<template<class, class> class X, class T, class U>
struct Foo<X<T, U>> { /* ... */ };
// etc., etc.
Foo<std::vector<int>>
теперь плохо сформирован без соответствующего исправления частичного упорядочения.