Что не так с этим:
#include <type_traits>
struct A;
template<typename T>
struct B
{
template<typename=std::enable_if<std::is_copy_constructible<T>::value>>
void f1() {}
};
template<typename T>
struct C {};
// Type your code here, or load an example.
int main() {
// Following fails
B<A> b;
// Could use this:
// b.f1<C>();
// This complies
C<A> c;
return 0;
}
/* This to be in or not doesn't make a difference
struct A
{};
*/
Я пробовал это здесь: https://godbolt.org/z/NkL44s с различными компиляторами:
- x86-64 gcc 9.2: компилирует
- x86-64 gcc (транк): сбой
- x86-64 clang 6.0.0: компилируется
- x86-64 clang 7.0.0 и более поздних версий: сбой
- x64 msvc v19.22: компилируется
- x64 msvc v19.23 (внутреннее тестирование): сбой
Так почему более поздние компиляторы отклоняют это? При создании экземпляра B<A>
неясно, в какой форме будет использоваться f1
или будет ли он использоваться вообще. Так почему компилятор жалуется на это? Не следует ли проверять функцию шаблона элемента f1
, только если она действительно используется?
Редактировать :
Как упоминалось в комментариях, я допустил непреднамеренную ошибку вкод выше: std::enable_if
должен был быть std::enable_if_t
, как на этой исправленной площадке: https://godbolt.org/z/cyuB3d
Это меняет картину компиляторов, передающих этот код без ошибок:
- gcc: сбой
- лязг: сбой
- x64 msvc v19.22: компилируется
- x64 msvc v19.23 (внутреннее тестирование): сбой
Однако остается вопрос: почему параметр шаблона по умолчанию для функции, которая никогда не используется, приводит к сбою компиляции?