Ist ein Ersetzungsfehler ein Fehler mit abhängigen, nicht typisierten Vorlagenparametern?
Nehmen wir an, ich habe diese Vorlagen-Aliase:
<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>
In GCC kann ich Folgendes tun:
<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>
Es druckt:
ist polymorph
ist nicht polymorph
Welches entspricht meinen Erwartungen.
Mit clang lässt sich dieser Code nicht kompilieren. Es werden die folgenden Fehlermeldungen ausgegeben.
<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>
Sollte es kompilieren? Welcher der beiden Compiler ist fehlerhaft?