A falha de substituição é um erro com parâmetros de modelo não-tipo dependentes?
Digamos que eu tenha esses aliases de modelo:
<code>enum class enabler {}; template <typename T> using EnableIf = typename std::enable_if<T::value, enabler>::type; template <typename T> using DisableIf = typename std::enable_if<!T::value, enabler>::type; </code>
Eu posso fazer o seguinte no GCC:
<code>#include <iostream> template <typename T, EnableIf<std::is_polymorphic<T>> = {}> void f(T) { std::cout << "is polymorphic\n"; } template <typename T, DisableIf<std::is_polymorphic<T>> = {}> void f(T) { std::cout << "is not polymorphic\n"; } struct foo { virtual void g() {} }; int main() { f(foo {}); f(int {}); } </code>
Imprime:
é polimórfico
não é polimórfico
Qual combina com minhas expectativas.
Com clang esse código não compila. Produz as seguintes mensagens de erro.
<code>test.cpp:11:58: error: expected expression template <typename T, EnableIf<std::is_polymorphic<T>> = {}> ^ test.cpp:14:59: error: expected expression template <typename T, DisableIf<std::is_polymorphic<T>> = {}> ^ test.cpp:20:3: error: no matching function for call to 'f' f(foo {}); ^ test.cpp:12:6: note: candidate template ignored: couldn't infer template argument '' void f(T) { std::cout << "is polymorphic\n"; } ^ test.cpp:15:6: note: candidate template ignored: couldn't infer template argument '' void f(T) { std::cout << "is not polymorphic\n"; } ^ test.cpp:21:3: error: no matching function for call to 'f' f(int {}); ^ test.cpp:12:6: note: candidate template ignored: couldn't infer template argument '' void f(T) { std::cout << "is polymorphic\n"; } ^ test.cpp:15:6: note: candidate template ignored: couldn't infer template argument '' void f(T) { std::cout << "is not polymorphic\n"; } ^ 4 errors generated. </code>
Deve compilar? Qual dos dois compiladores está com defeito?