Неоднозначный вывод в конструкторе шаблонов SFINAE на clang , а не на g

#c #g #c 17 #clang #sfinae

#c #g #c 17 #clang #sfinae

Вопрос:

Следующий пример:

 #include <iostream>

template<typename T>
struct X {
    static constexpr bool B = std::is_same_v<T, int>;
    
    template <bool Z = B, std::enable_if_t<Z, int> = 0>
    X(T t) { std::cout << t << " - intn"; }
    
    template <bool Z = B, std::enable_if_t<!Z, int> = 0>
    X(T t) { std::cout << t << " - not intn"; }
};

int main()
{
    X x(5);
    
    X y(5.0);
}
 

Приводит к ошибке неоднозначного вывода при компиляции с использованием clang (я пробовал до 11.0) -std=c 1z . Компиляция успешно завершается с помощью g 9.3.0.

Кто прав? Почему? Есть ли ошибка, связанная с этим?

Комментарии:

1. Вы можете добавить пользовательское руководство по выводу template <typename T> X(T) -> X<T>; .

2. @Jarod42 Это, похоже, работает и в моем случае использования, отличном от MWE, спасибо! Поскольку вопрос все еще стоит, я все равно оставлю его здесь.

3. Если вы используете std::is_same_v<T, int> непосредственно вместо B , Лязг утихает. Я предполагаю, что для Клэнга это проблема с курицей и яйцом. Зависимый от значения член B специализации необходим для вывода самой специализации. Если вы избегаете использования B , сгенерированные компилятором руководства по дедукции будут работать просто отлично.

4. @StoryTeller-UnslanderMonica: не с requires демонстрацией .

5. @Jarod42 — Нормативный текст не переносит ограничений на руководства по дедукции, созданные компилятором ( timsong-cpp.github.io/cppwp/n4861/over.match.class.deduct#1.1 ). Интересно, это дефект или здесь кроется более глубокий смысл?