Während der Auflösung einer Überladung einer Template-Member-Funktion einer Basisklasse beobachtete ich ein unterschiedliches Verhalten zwischen g ++ (5.2.1-23) und clang (3.8.0), mit -std=c++14
.C++ Template-Überladung mit enable_if: anderes Verhalten mit g ++ und clang
#include <iostream>
#include <type_traits>
struct Base
{
template <typename T>
auto a(T t) -> void {
std::cout<< "False\n";
}
};
template <bool Bool>
struct Derived : public Base
{
using Base::a;
template <typename T, bool B = Bool>
auto a(T t) -> std::enable_if_t<B, void>
{
std::cout<< "True\n";
}
};
int main()
{
Derived<true> d;
d.a(1); // fails with g++, prints "true" with clang
Derived<false> d2;
d2.a(1); // fails with clang++, prints "false" with g++
}
Der Aufruf von Derived<true>::a
nicht mit g ++ mit der folgenden Meldung:
test.cc: In function ‘int main()’:
test.cc:28:8: error: call of overloaded ‘a(int)’ is ambiguous
d.a(1);
^
test.cc:18:8: note: candidate: std::enable_if_t<B, void> Derived<Bool>::a(T) [with T = int; bool B = true; bool Bool = true; std::enable_if_t<B, void> = void]
auto a(T t) -> std::enable_if_t<B, void>
^
test.cc:7:8: note: candidate: void Base::a(T) [with T = int]
auto a(T t) -> void {
^
und der Aufruf von Derived<false>::a
nicht mit Klirren ++ mit der folgenden Meldung:
test.cc:32:6: error: no matching member function for call to 'a'
d2.a(1);
~~~^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/type_traits:2388:44: note: candidate template ignored: disabled by 'enable_if' [with T = int, B = false]
using enable_if_t = typename enable_if<_Cond, _Tp>::type;
^
Meine Vermutung ist, dass Sie interpretieren das using Base::a;
anders und es wird nicht in clang berücksichtigt, während es in g ++ (vielleicht zu viel) berücksichtigt wird. Was ich dachte, würde passieren, wenn Derived
true
als Parameter hat, dann wird der Anruf von a()
zu Derived
Implementierung gesendet, während, wenn der Parameter false
ist, der Anruf an Base::a
gesendet wird.
Sind beide falsch? Wer hat Recht? An wen sollte ich einen Fehlerbericht senden? Kann jemand erklären, was vor sich geht?
Dank
Es ist entweder versteckt und nicht Teil der Überladung gesetzt, oder es ist sichtbar und so Teil der Überlast eingestellt. "Manchmal versteckt" ergibt keinen Sinn. –
Also, wenn ich richtig verstehe, ist g ++ falsch, weil ein Konflikt mit einem 'using' nicht berücksichtigt werden sollte, und clang ist falsch, denn wenn nichts gefunden wird, sollte es einen Blick auf das' using' werfen, richtig? Daher sollte ich einen Fehlerbericht für beide Compiler einreichen. –
@ VTolmer Basierend auf der Standard-Formulierung glaube ich, dass dies der Fall ist. – 101010