#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 ). Интересно, это дефект или здесь кроется более глубокий смысл?